public virtual void RetainAll <U>(SCG.IEnumerable <U> items) where U : T { updatecheck(); HashBag <T> res = new HashBag <T>(itemequalityComparer); foreach (U item in items) { KeyValuePair <T, int> p = new KeyValuePair <T, int>(item); if (dict.Find(ref p)) { KeyValuePair <T, int> q = p; if (res.dict.Find(ref q)) { if (q.Value < p.Value) { q.Value++; res.dict.Update(q); res.size++; } } else { q.Value = 1; res.dict.Add(q); res.size++; } } } if (size == res.size) { return; } CircularQueue <T> wasRemoved = null; if ((ActiveEvents & EventTypeEnum.Removed) != 0) { wasRemoved = new CircularQueue <T>(); foreach (KeyValuePair <T, int> p in dict) { int removed = p.Value - res.ContainsCount(p.Key); if (removed > 0) #warning We could send bag events here easily using a CircularQueue of (should?) { for (int i = 0; i < removed; i++) { wasRemoved.Enqueue(p.Key); } } } } dict = res.dict; size = res.size; if ((ActiveEvents & EventTypeEnum.Removed) != 0) { raiseForRemoveAll(wasRemoved); } else if ((ActiveEvents & EventTypeEnum.Changed) != 0) { raiseCollectionChanged(); } }