private void RefreshPropertyTracker(string propertyName, bool raiseEvent)
        {
            // Determine the new value
            var prop = TrackedObject.GetType().GetProperty(propertyName);

            if (prop == null)
            {
                return; // Was probably an indexer that changed
            }
            var newValue = prop.GetValue(TrackedObject);

            // If no ObjectTracker exists for the property, the old value was null
            TrackerToken trackerToken;
            object       oldValue = null;

            if (_propertyTrackers.TryGetValue(propertyName, out trackerToken))
            {
                // Detach old tracker from old value and remove it
                oldValue = trackerToken.Tracker.TrackedObject;
                trackerToken.Dispose();
                _propertyTrackers.Remove(propertyName);
            }

            if (newValue != null)
            {
                // Add a new tracker for the new value
                var token = new TrackerToken(newValue, propertyName, Tracker);
                _propertyTrackers.Add(propertyName, token);
            }

            // Notify that property changed
            if (raiseEvent)
            {
                Tracker.RaisePropertyPathChanged(new PropertyPathChangedEventArgs(propertyName, TrackedObject, oldValue, newValue));
            }
        }
        private void InsertTrackerAt(int index, object item)
        {
            var token = new TrackerToken(item, index.ToString(), Tracker);

            _itemTrackers.Insert(index, token);
        }