Пример #1
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TSource> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;

            foreach (ICollectionChangedNotificationResult <TSource> change in sources)
            {
                if (change.IsReset)
                {
                    OnDetach();
                    OnAttach();
                    OnCleared();
                    notification.TurnIntoReset();
                    return(notification);
                }

                if (change.Source == source)
                {
                    NotifySource(change, added, removed);
                }
                else
                {
                    NotifySource2(change, added, removed);
                }
            }

            OnRemoveItems(removed);
            OnAddItems(added);
            return(notification);
        }
Пример #2
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TSource> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;
            var moved   = notification.MovedItems;

            foreach (ICollectionChangedNotificationResult change in sources)
            {
                if (change.IsReset)
                {
                    OnCleared();
                    notification.TurnIntoReset();
                    return(notification);
                }

                if (change.AddedItems != null)
                {
                    added.AddRange(SL.Cast <TSource>(change.AddedItems));
                }
                if (change.RemovedItems != null)
                {
                    removed.AddRange(SL.Cast <TSource>(change.RemovedItems));
                }
                if (change.MovedItems != null)
                {
                    moved.AddRange(SL.Cast <TSource>(change.MovedItems));
                }
            }

            RaiseEvents(added, removed, moved);
            return(notification);
        }
Пример #3
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <INotifyGrouping <TKey, TItem> > .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;

            foreach (var change in sources)
            {
                if (change.Source == source)
                {
                    var sourceChange = (ICollectionChangedNotificationResult <TItem>)change;
                    if (sourceChange.IsReset)
                    {
                        OnDetach();
                        OnAttach();
                        OnCleared();
                        notification.TurnIntoReset();
                        return(notification);
                    }
                    else
                    {
                        NotifySource(sourceChange, added, removed);
                    }
                }
                else
                {
                    var keyChange = (IValueChangedNotificationResult <TKey>)change;
                    var tagged    = (TaggedObservableValue <TKey, TItem>)keyChange.Source;

                    ObservableGroup <TKey, TItem> group;
                    if (groups.TryGetValue(keyChange.OldValue, out group))
                    {
                        group.Items.Remove(tagged.Tag);
                        if (group.Count == 0)
                        {
                            groups.Remove(keyChange.OldValue);
                            removed.Add(group);
                        }
                    }

                    if (!groups.TryGetValue(keyChange.NewValue, out group))
                    {
                        group = new ObservableGroup <TKey, TItem>(keyChange.NewValue);
                        groups.Add(keyChange.NewValue, group);
                        added.Add(group);
                    }
                    group.Items.Add(tagged.Tag);
                }
            }

            if (added.Count == 0 && removed.Count == 0)
            {
                return(UnchangedNotificationResult.Instance);
            }

            OnRemoveItems(removed.Cast <ObservableGroup <TKey, TItem> >());
            OnAddItems(added.Cast <ObservableGroup <TKey, TItem> >());
            return(notification);
        }
Пример #4
0
 public override INotificationResult Notify(IList <INotificationResult> sources)
 {
     if (sources.Count == 0)
     {
         OnCleared();
         return(CollectionChangedNotificationResult <T> .Create(this, true));
     }
     else
     {
         var change = (ICollectionChangedNotificationResult)sources[0];
         if (change.IsReset)
         {
             OnCleared();
         }
         else
         {
             if (change.RemovedItems != null)
             {
                 OnRemoveItems(change.RemovedItems.Cast <T>());
             }
             if (change.AddedItems != null)
             {
                 OnAddItems(change.AddedItems.Cast <T>());
             }
         }
         return(CollectionChangedNotificationResult <T> .Transfer(change, this));
     }
 }
Пример #5
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TResult> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;

            foreach (var change in sources)
            {
                if (change.Source == source)
                {
                    var sourceChange = (ICollectionChangedNotificationResult <TSource>)change;
                    if (sourceChange.IsReset)
                    {
                        OnDetach();
                        OnAttach();
                        OnCleared();
                        notification.TurnIntoReset();
                        return(notification);
                    }
                    else
                    {
                        NotifySource(sourceChange, added, removed);
                    }
                }
                else
                {
                    var innerCollectionChange = change as ICollectionChangedNotificationResult;
                    if (innerCollectionChange != null)
                    {
                        if (innerCollectionChange.AddedItems != null)
                        {
                            added.AddRange(innerCollectionChange.AddedItems.Cast <TResult>());
                        }
                        if (innerCollectionChange.RemovedItems != null)
                        {
                            removed.AddRange(innerCollectionChange.RemovedItems.Cast <TResult>());
                        }
                    }
                    else
                    {
                        var subSourceChange = (IValueChangedNotificationResult <IEnumerable <TResult> >)change;
                        if (subSourceChange.OldValue != null)
                        {
                            removed.AddRange(subSourceChange.OldValue);
                        }
                        if (subSourceChange.NewValue != null)
                        {
                            added.AddRange(subSourceChange.NewValue);
                        }
                    }
                }
            }

            OnRemoveItems(removed);
            OnAddItems(added);
            return(notification);
        }
Пример #6
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TItem> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;
            var moved   = notification.MovedItems;

            foreach (var change in sources)
            {
                if (change.Source == source)
                {
                    var sourceChange = (ICollectionChangedNotificationResult <TItem>)change;
                    if (sourceChange.IsReset)
                    {
                        OnDetach();
                        OnAttach();
                        OnCleared();
                        notification.TurnIntoReset();
                        return(notification);
                    }
                    else
                    {
                        NotifySource(sourceChange, added, removed);
                    }
                }
                else
                {
                    var lambdaResult = (TaggedObservableValue <TKey, SequenceInfo>)change.Source;
                    var searchTree   = lambdaResult.Tag.SearchTree;
                    var keyChange    = (IValueChangedNotificationResult <TKey>)change;

                    Collection <TItem> itemSequence;
                    if (searchTree.TryGetValue(keyChange.OldValue, out itemSequence))
                    {
                        itemSequence.Remove(lambdaResult.Tag.Item);
                        if (itemSequence.Count == 0)
                        {
                            searchTree.Remove(keyChange.OldValue);
                        }
                    }
                    if (!searchTree.TryGetValue(keyChange.NewValue, out itemSequence))
                    {
                        itemSequence = new Collection <TItem>();
                        searchTree.Add(keyChange.NewValue, itemSequence);
                    }
                    itemSequence.Add(lambdaResult.Tag.Item);

                    moved.Add(lambdaResult.Tag.Item);
                }
            }

            OnRemoveItems(removed);
            OnAddItems(added);
            OnMoveItems(moved);
            return(notification);
        }
Пример #7
0
            public Notifiable(IModelElement element)
            {
                this.element      = element;
                this.successors   = new MultiSuccessorList();
                this.metadata     = new ExecutionMetaData();
                this.notification = CollectionChangedNotificationResult <IModelElement> .Create(this, false);

                element.BubbledChange += Element_BubbledChange;
            }
Пример #8
0
            public INotificationResult Notify(IList <INotificationResult> sources)
            {
                isNotified = false;
                var result = notification;

                notification = CollectionChangedNotificationResult <IModelElement> .Create(this, false);

                return(result);
            }
Пример #9
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TItem> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;
            var moved   = notification.MovedItems;

            foreach (var change in sources)
            {
                if (change.Source == source)
                {
                    var sourceChange = (ICollectionChangedNotificationResult <TItem>)change;
                    if (sourceChange.IsReset)
                    {
                        OnDetach();
                        OnAttach();
                        OnCleared();
                        notification.TurnIntoReset();
                        return(notification);
                    }
                    else
                    {
                        NotifySource(sourceChange, added, removed);
                    }
                }
                else
                {
                    var tagged    = (TaggedObservableValue <TKey, Multiplicity <TItem> >)change.Source;
                    var keyChange = (IValueChangedNotificationResult <TKey>)change;

                    Collection <TItem> sequence;
                    if (searchTree.TryGetValue(keyChange.OldValue, out sequence))
                    {
                        sequence.Remove(tagged.Tag.Item);
                        if (sequence.Count == 0)
                        {
                            searchTree.Remove(keyChange.OldValue);
                        }
                    }
                    if ((sources.Count == 1 || !removed.Contains(tagged.Tag.Item)))
                    {
                        if (!searchTree.TryGetValue(keyChange.NewValue, out sequence))
                        {
                            sequence = new Collection <TItem>();
                            searchTree.Add(keyChange.NewValue, sequence);
                        }
                        sequence.Add(tagged.Tag.Item);
                        moved.Add(tagged.Tag.Item);
                    }
                }
            }

            RaiseEvents(added, removed, moved);
            return(notification);
        }
Пример #10
0
 public override INotificationResult Notify(IList <INotificationResult> sources)
 {
     if (ShouldRecompute(sources))
     {
         Recompute();
         return(CollectionChangedNotificationResult <IEnumerable <T> > .Create(this, isReset : true));
     }
     else
     {
         return(UnchangedNotificationResult.Instance);
     }
 }
Пример #11
0
            public Notifiable(IModelElement element)
            {
                this.element      = element;
                this.successors   = new MultiSuccessorList();
                this.metadata     = new ExecutionMetaData();
                this.notification = CollectionChangedNotificationResult <IModelElement> .Create(this, false);

                element.ParentChanged += Ancestor_ParentChanged;
                foreach (var ancestor in this)
                {
                    ancestor.ParentChanged += Ancestor_ParentChanged;
                }
            }
Пример #12
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TSource> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;
            var moved   = notification.MovedItems;

            foreach (ICollectionChangedNotificationResult change in sources)
            {
                if (change.IsReset)
                {
                    OnCleared();
                    notification.TurnIntoReset();
                    return(notification);
                }

                var offset = change.Source == source ? 0 : SL.Count(source);
                if (change.AddedItems != null)
                {
                    added.AddRange(SL.Cast <TSource>(change.AddedItems));
                    if (change.NewItemsStartIndex != -1)
                    {
                        notification.UpdateNewStartIndex(offset + change.NewItemsStartIndex);
                    }
                }
                if (change.RemovedItems != null)
                {
                    removed.AddRange(SL.Cast <TSource>(change.RemovedItems));
                    if (change.OldItemsStartIndex != -1)
                    {
                        notification.UpdateOldStartIndex(offset + change.OldItemsStartIndex);
                    }
                }
                if (change.MovedItems != null)
                {
                    moved.AddRange(SL.Cast <TSource>(change.MovedItems));
                    if (change.NewItemsStartIndex != -1)
                    {
                        notification.UpdateNewStartIndex(offset + change.NewItemsStartIndex);
                    }
                    if (change.OldItemsStartIndex != -1)
                    {
                        notification.UpdateOldStartIndex(offset + change.OldItemsStartIndex);
                    }
                }
            }

            RaiseEvents(added, removed, moved, notification.OldItemsStartIndex, notification.NewItemsStartIndex);
            return(notification);
        }
Пример #13
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var change = (ICollectionChangedNotificationResult <TSource>)sources[0];

            if (change.IsReset)
            {
                OnDetach();
                OnAttach();
                OnCleared();
                return(CollectionChangedNotificationResult <TSource> .Create(this, true));
            }

            var notification = CollectionChangedNotificationResult <TSource> .Create(this);

            var removed = notification.RemovedItems;
            var added   = notification.AddedItems;

            if (change.RemovedItems != null)
            {
                foreach (var item in change.RemovedItems)
                {
                    if (RemoveItem(item))
                    {
                        removed.Add(item);
                    }
                }
            }

            if (change.AddedItems != null)
            {
                foreach (var item in change.AddedItems)
                {
                    if (AddItem(item))
                    {
                        added.Add(item);
                    }
                }
            }

            OnRemoveItems(removed);
            OnAddItems(added);
            return(notification);
        }
Пример #14
0
        void SequencesCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.Action != NotifyCollectionChangedAction.Reset)
            {
                var notification = CollectionChangedNotificationResult <T> .Create(this);

                var removed = notification.RemovedItems;
                var added   = notification.AddedItems;

                if (e.OldItems != null)
                {
                    foreach (IEnumerable <T> sequence in e.OldItems)
                    {
                        removed.AddRange(sequence);
                        INotifyCollectionChanged notifier = sequence as INotifyCollectionChanged;
                        if (notifier != null)
                        {
                            var listener = changeListener[sequence];
                            listener.Unsubscribe();
                            changeListener.Remove(sequence);
                        }
                    }
                }
                if (e.NewItems != null)
                {
                    foreach (IEnumerable <T> sequence in e.NewItems)
                    {
                        added.AddRange(sequence);
                        INotifyCollectionChanged notifier = sequence as INotifyCollectionChanged;
                        if (notifier != null)
                        {
                            var listener = new CollectionChangeListener <T>(this);
                            listener.Subscribe(notifier);
                            changeListener.Add(sequence, listener);
                        }
                    }
                }

                ExecutionMetaData.Results.Add(notification);
            }
            ExecutionEngine.Current.InvalidateNode(this);
        }
Пример #15
0
            public override INotificationResult Notify(IList <INotificationResult> sources)
            {
                var notification = CollectionChangedNotificationResult <TResult> .Create(this);

                var added   = notification.AddedItems;
                var removed = notification.RemovedItems;

                foreach (var change in sources)
                {
                    if (change.Source == SubSource)
                    {
                        var subSourceChange = (IValueChangedNotificationResult)change;
                        DetachSubSourceValue((IEnumerable <TIntermediate>)subSourceChange.OldValue, removed);
                        OnAttach();
                        added.AddRange(SL.Select(Results.Values, res => res.Value));
                    }
                    else if (change.Source is TaggedObservableValue <TResult, int> )
                    {
                        var resultChange = (IValueChangedNotificationResult <TResult>)change;
                        removed.Add(resultChange.OldValue);
                        added.Add(resultChange.NewValue);
                    }
                    else
                    {
                        var subSourceValueChange = (ICollectionChangedNotificationResult <TIntermediate>)change;
                        if (subSourceValueChange.IsReset)
                        {
                            DetachSubSourceValue(SubSource.Value, removed);
                            AttachSubSourceValue();
                            added.AddRange(SL.Select(Results.Values, res => res.Value));
                        }
                        else
                        {
                            NotifySubSourceValue(added, removed, subSourceValueChange);
                        }
                    }
                }

                RaiseEvents(added, removed, null);
                return(notification);
            }
Пример #16
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TResult> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;

            foreach (var change in sources)
            {
                if (change.Source == source)
                {
                    var sourceChange = (ICollectionChangedNotificationResult <TSource>)change;
                    if (sourceChange.IsReset)
                    {
                        OnDetach();
                        OnAttach();
                        OnCleared();
                        notification.TurnIntoReset();
                        return(notification);
                    }
                    else
                    {
                        NotifySource(sourceChange, added, removed);
                    }
                }
                else
                {
                    var subSourceChange = (ICollectionChangedNotificationResult <TResult>)change;
                    if (subSourceChange.RemovedItems != null)
                    {
                        removed.AddRange(subSourceChange.RemovedItems);
                    }
                    if (subSourceChange.AddedItems != null)
                    {
                        added.AddRange(subSourceChange.AddedItems);
                    }
                }
            }
            RaiseEvents(added, removed, null);
            return(notification);
        }
Пример #17
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var change = (ICollectionChangedNotificationResult)sources[0];

            if (change.IsReset)
            {
                OnCleared();
                return(CollectionChangedNotificationResult <T> .Create(this, true));
            }

            var notification = CollectionChangedNotificationResult <T> .Create(this);

            var removed = notification.RemovedItems;
            var added   = notification.AddedItems;
            var moved   = notification.MovedItems;

            removed.AddRange(change.RemovedItems.OfType <T>());
            added.AddRange(change.AddedItems.OfType <T>());
            moved.AddRange(change.MovedItems.OfType <T>());

            RaiseEvents(added, removed, moved);
            return(notification);
        }
Пример #18
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            ICollectionChangedNotificationResult <TSource> sourceChange  = null;
            ICollectionChangedNotificationResult <TSource> source2Change = null;

            if (sources[0].Source == source)
            {
                sourceChange = (ICollectionChangedNotificationResult <TSource>)sources[0];
            }
            else
            {
                source2Change = (ICollectionChangedNotificationResult <TSource>)sources[0];
            }

            if (sources.Count > 1)
            {
                if (sources[1].Source == source)
                {
                    sourceChange = (ICollectionChangedNotificationResult <TSource>)sources[1];
                }
                else
                {
                    source2Change = (ICollectionChangedNotificationResult <TSource>)sources[1];
                }
            }

            var notification = CollectionChangedNotificationResult <TSource> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;

            if (source2Change != null)
            {
                if (source2Change.IsReset)
                {
                    sourceItems.Clear();
                    OnCleared();
                    notification.TurnIntoReset();
                    return(notification);
                }
                else
                {
                    NotifySource2(source2Change, added, removed);
                }
            }

            if (sourceChange != null)
            {
                if (sourceChange.IsReset)
                {
                    OnCleared();
                    notification.TurnIntoReset();
                    return(notification);
                }
                else
                {
                    NotifySource(sourceChange, added, removed);
                }
            }

            OnRemoveItems(removed);
            OnAddItems(added);
            return(notification);
        }
Пример #19
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <T> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;

            foreach (var change in sources)
            {
                if (change.Source == source)
                {
                    var sourceChange = (ICollectionChangedNotificationResult <T>)change;
                    if (sourceChange.IsReset)
                    {
                        foreach (var item in lambdaInstances.Values)
                        {
                            item.Successors.Unset(this);
                        }
                        lambdaInstances.Clear();
                        foreach (var item in source)
                        {
                            AttachItem(item);
                        }
                        OnCleared();
                        notification.TurnIntoReset();
                        return(notification);
                    }
                    else
                    {
                        NotifySource(sourceChange, added, removed);
                    }
                }
                else if (nullCheck != null && change.Source == nullCheck)
                {
                    if (nullCheck.Value)
                    {
                        added.AddRange(SL.Repeat(default(T), nulls));
                    }
                    else
                    {
                        removed.AddRange(SL.Repeat(default(T), nulls));
                    }
                }
                else
                {
                    var lambdaResult = (TaggedObservableValue <bool, ItemMultiplicity>)change.Source;
                    if (lambdaResult.Value)
                    {
                        added.AddRange(SL.Repeat(lambdaResult.Tag.Item, lambdaResult.Tag.Multiplicity));
                    }
                    else
                    {
                        removed.AddRange(SL.Repeat(lambdaResult.Tag.Item, lambdaResult.Tag.Multiplicity));
                    }
                }
            }

            OnRemoveItems(removed);
            OnAddItems(added);

            return(notification);
        }
Пример #20
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TResult> .Create(this);

            var added   = notification.AddedItems;
            var removed = notification.RemovedItems;

            foreach (var change in sources)
            {
                if (change.Source == source)
                {
                    var sourceChange = (ICollectionChangedNotificationResult <TSource>)change;
                    if (sourceChange.IsReset)
                    {
                        foreach (var item in lambdaInstances.Values)
                        {
                            item.Successors.Unset(this);
                        }
                        lambdaInstances.Clear();
                        foreach (var item in source)
                        {
                            AttachItem(item);
                        }
                        OnCleared();
                        notification.TurnIntoReset();
                        return(notification);
                    }
                    else
                    {
                        NotifySource(sourceChange, added, removed, sources.Count > 1);
                    }
                }
                else
                {
                    var itemChange = (IValueChangedNotificationResult <TResult>)change;
                    if (sources.Count > 1)
                    {
                        // if there are multiple changes, we need to check whether the change belongs to items
                        // we just added or removed
                        var addIndex    = added.IndexOf(itemChange.OldValue);
                        var removeIndex = removed.IndexOf(itemChange.NewValue);
                        if (addIndex == -1)
                        {
                            if (removeIndex == -1)
                            {
                                // the changed item was not added or removed
                                removed.Add(itemChange.OldValue);
                                added.Add(itemChange.NewValue);
                            }
                            else
                            {
                                // if the value is removed, remove the old value only
                                removed[removeIndex] = itemChange.OldValue;
                            }
                        }
                        else
                        {
                            if (removeIndex == -1)
                            {
                                // an added item changed
                                added[addIndex] = itemChange.NewValue;
                            }
                            else
                            {
                                // an added item turns out to be the same as a removed item, so erase the change
                                added.RemoveAt(addIndex);
                                removed.RemoveAt(removeIndex);
                            }
                        }
                    }
                    else
                    {
                        removed.Add(itemChange.OldValue);
                        added.Add(itemChange.NewValue);
                    }
                }
            }
            RaiseEvents(added, removed, null);
            return(notification);
        }
Пример #21
0
        public override INotificationResult Notify(IList <INotificationResult> sources)
        {
            var notification = CollectionChangedNotificationResult <TResult> .Create(this);

            var  added   = notification.AddedItems;
            var  removed = notification.RemovedItems;
            bool reset   = false;

            foreach (var change in sources)
            {
                if (change.Source == outerSource)
                {
                    var outerChange = (ICollectionChangedNotificationResult <TOuter>)change;
                    if (outerChange.IsReset)
                    {
                        foreach (var group in groups.Values)
                        {
                            foreach (var val in group.OuterKeys)
                            {
                                val.Successors.Unset(this);
                            }
                            group.OuterKeys.Clear();
                            foreach (var stack in group.Results.Values)
                            {
                                removed.AddRange(stack.Select(s => s.Value));
                                foreach (var val in stack)
                                {
                                    val.Successors.Unset(this);
                                }
                            }
                            group.Results.Clear();
                        }
                        outerValues.Clear();

                        if (reset || observableInnerSource == null) //both source collections may be reset, only return after handling both
                        {
                            OnCleared();
                            notification.TurnIntoReset();
                            return(notification);
                        }
                        reset = true;
                    }
                    else
                    {
                        NotifyOuter(outerChange, added, removed);
                    }
                }
                else if (change.Source == observableInnerSource)
                {
                    var innerChange = (ICollectionChangedNotificationResult <TInner>)change;
                    if (innerChange.IsReset)
                    {
                        foreach (var group in groups.Values)
                        {
                            foreach (var val in group.InnerKeys)
                            {
                                val.Successors.Unset(this);
                            }
                            group.InnerKeys.Clear();
                            foreach (var stack in group.Results.Values)
                            {
                                removed.AddRange(stack.Select(s => s.Value));
                                foreach (var val in stack)
                                {
                                    val.Successors.Unset(this);
                                }
                            }
                            group.Results.Clear();
                        }
                        innerValues.Clear();

                        if (reset) //both source collections may be reset, only return after handling both
                        {
                            OnCleared();
                            notification.TurnIntoReset();
                            return(notification);
                        }
                        reset = true;
                    }
                    else
                    {
                        NotifyInner(innerChange, added, removed);
                    }
                }
                else if (change is IValueChangedNotificationResult <TKey> keyChange)
                {
                    if (keyChange.Source is TaggedObservableValue <TKey, TOuter> )
                    {
                        NotifyOuterKey(keyChange, added, removed);
                    }
                    else
                    {
                        NotifyInnerKey(keyChange, added, removed);
                    }
                }
                else
                {
                    var resultChange = (IValueChangedNotificationResult <TResult>)change;
                    removed.Add(resultChange.OldValue);
                    added.Add(resultChange.NewValue);
                }
            }

            if (reset) //only one source was reset
            {
                OnCleared();
                notification.TurnIntoReset();
                return(notification);
            }

            RaiseEvents(added, removed, null);
            return(notification);
        }