private NotifyCollectionChangedEventArgs Update(IEnumerable <T> updated, IReadOnlyList <NotifyCollectionChangedEventArgs> collectionChanges, Action <PropertyChangedEventArgs> propertyChanged, Action <NotifyCollectionChangedEventArgs> collectionChanged)
        {
            var retry = 0;

            while (true)
            {
                this.temp.Clear();
                try
                {
                    this.temp.AddRange(updated);
                    break;
                }
                catch (InvalidOperationException e) when(e.Message == Exceptions.CollectionWasModified.Message &&
                                                         retry < 5)
                {
                    retry++;
                }
            }

            if (propertyChanged != null || collectionChanged != null)
            {
                var change = Diff.CollectionChange(this, this.temp, collectionChanges);
                this.Items.Clear();
                ((List <T>) this.Items).AddRange(this.temp);
                this.temp.Clear();
                return(change);
            }

            this.Items.Clear();
            ((List <T>) this.Items).AddRange(this.temp);
            this.temp.Clear();
            return(null);
        }
        private NotifyCollectionChangedEventArgs Update(IReadOnlyList <T> updated, IReadOnlyList <NotifyCollectionChangedEventArgs> collectionChanges, bool calculateDiff)
        {
            NotifyCollectionChangedEventArgs change = calculateDiff
                                                          ? Diff.CollectionChange(this.inner, updated, collectionChanges)
                                                          : null;

            if (!calculateDiff || change != null)
            {
                this.inner.Clear();
                this.inner.AddRange(updated);
            }

            return(change);
        }