public IObservable <IChangeSet <T> > Run() { return(Observable.Create <IChangeSet <T> >(observer => { var locker = new object(); Func <T, bool> predicate = t => false; var all = new List <ItemWithMatch>(); var filtered = new ChangeAwareList <ItemWithMatch>(); //requery when predicate changes var predicateChanged = _predicates.Synchronize(locker) .Select(newPredicate => { predicate = newPredicate; Requery(predicate, all, filtered); return filtered.CaptureChanges(); }); /* * Apply the transform operator so 'IsMatch' state can be evalutated and captured one time only * This is to eliminate the need to re-apply the predicate when determining whether an item was previously matched */ var filteredResult = _source.Synchronize(locker) .Transform(t => new ItemWithMatch(t, predicate(t))) .Select(changes => { all.Clone(changes); //keep track of all changes filtered.Filter(changes, iwm => iwm.IsMatch); //maintain filtered result return filtered.CaptureChanges(); }); return predicateChanged.Merge(filteredResult) .NotEmpty() .Select(changes => changes.Transform(iwm => iwm.Item)) .SubscribeSafe(observer); })); }