public Dictionary <TKey, HashSet <IDictionaryObserver <TKey, TValue> > > AddPartialObserver(
            IDictionaryObserver <TKey, TValue> observer, params TKey[] keys)
        {
            if (observer is null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (keys is null)
            {
                throw new ArgumentNullException(nameof(keys));
            }

            foreach (var key in keys)
            {
                _observers.AddOrUpdate(key, new HashSet <IDictionaryObserver <TKey, TValue> > {
                    observer
                }, (k, o) =>
                {
                    o.Add(observer);
                    return(o);
                });
            }

            return(keys.ToDictionary(k => k, k => new HashSet <IDictionaryObserver <TKey, TValue> > {
                observer
            }));
        }
        public Dictionary <TKey, HashSet <IDictionaryObserver <TKey, TValue> > > RemovePartialObserver(
            IDictionaryObserver <TKey, TValue> observer)
        {
            if (observer is null)
            {
                throw new ArgumentNullException(nameof(observer));
            }

            var removed = _observers.Where(pair => pair.Value.Contains(observer) && pair.Value.Remove(observer)).Select(pair => pair.Key);

            return(removed.ToDictionary(k => k, k => new HashSet <IDictionaryObserver <TKey, TValue> > {
                observer
            }));
        }
        public Dictionary <TKey, HashSet <IDictionaryObserver <TKey, TValue> > > RemovePartialObserver(
            IDictionaryObserver <TKey, TValue> observer, params TKey[] keys)
        {
            if (observer is null)
            {
                throw new ArgumentNullException(nameof(observer));
            }
            if (keys is null)
            {
                throw new ArgumentNullException(nameof(keys));
            }

            var removed = keys.Where(key =>
                                     _observers.TryGetValue(key, out var observers) && observers.Contains(observer) && observers.Remove(observer));

            return(removed.ToDictionary(k => k, k => new HashSet <IDictionaryObserver <TKey, TValue> > {
                observer
            }));
        }