Catel.Data.ChangeNotificationWrapper.UnsubscribeNotifyChangedEvent C# (CSharp) Method

UnsubscribeNotifyChangedEvent() private method

private UnsubscribeNotifyChangedEvent ( object value, EventChangeType eventChangeType, ICollection parentCollection ) : void
value object
eventChangeType EventChangeType
parentCollection ICollection
return void
        private void UnsubscribeNotifyChangedEvent(object value, EventChangeType eventChangeType, ICollection parentCollection)
        {
            if (value == null)
            {
                return;
            }

            lock (_lockObject)
            {
                ConditionalWeakTable<object, IWeakEventListener> eventsTable;
                List<IWeakEventListener> eventsList;

                switch (eventChangeType)
                {
                    case EventChangeType.Property:
                        eventsTable = _weakPropertyChangedListenersTable;
                        eventsList = _weakPropertyChangedListeners;

                        if (parentCollection != null)
                        {
                            List<WeakReference> collectionItems;
                            if (_collectionItems.TryGetValue(parentCollection, out collectionItems))
                            {
                                // TODO: Consider less costly way to determine this
                                for (var i = 0; i < collectionItems.Count; i++)
                                {
                                    if (ReferenceEquals(collectionItems[i].Target, value))
                                    {
                                        collectionItems.RemoveAt(i--);
                                        break;
                                    }
                                }
                            }
                        }
                        break;

                    case EventChangeType.Collection:
                        eventsTable = _weakCollectionChangedListenersTable;
                        eventsList = _weakCollectionChangedListeners;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException("eventChangeType");
                }

                IWeakEventListener oldSubscription;
                if (eventsTable != null && eventsTable.TryGetValue(value, out oldSubscription))
                {
                    if (oldSubscription != null)
                    {
                        oldSubscription.Detach();

                        eventsList.Remove(oldSubscription);
                    }

                    eventsTable.Remove(value);
                }

                if (value is ICollection)
                {
                    List<WeakReference> collectionItems;
                    if (_collectionItems.TryGetValue(value, out collectionItems))
                    {
                        foreach (var item in collectionItems)
                        {
                            if (item.IsAlive)
                            {
                                var actualItem = item.Target;
                                UnsubscribeNotifyChangedEvents(actualItem, parentCollection);
                            }
                        }

                        collectionItems.Clear();
                        _collectionItems.Remove(value);
                    }
                }
            }
        }
        #endregion