TrackingMultimap extends AbstractMap<K, Set<V>> { @SuppressWarnings("unchecked") @Override public Set<V> remove(Object key) { Set<V> stored = newHashSetNullSafe(data.get(key)); if(stored != null) { for (V element : stored) { delete((K) key, element); } } Set<V> values = data.get(key); if(values != null && values.isEmpty()) { data.remove(key); } if(comparator != null && (min != null && min.equals(key)) || (max != null && max.equals(key))) { SortedSet<K> sorted = Sets.newTreeSet(comparator); sorted.addAll(data.keySet()); min = sorted.isEmpty() ? null : sorted.first(); max = sorted.isEmpty() ? null : sorted.last(); } return stored; } protected  TrackingMultimap(Map<K, Set<V>> delegate,
            @Nullable Comparator<K> comparator); boolean containsDataType(DataType type); long count(); boolean delete(K key, V value); double distinctiveness(); @Override Set<Entry<K, Set<V>>> entrySet(); @SuppressWarnings("unchecked") @Override boolean equals(Object obj); @Override Set<V> get(Object key); @Override int hashCode(); boolean hasValue(V value); boolean insert(K key, V value); K max(); Set<V> merge(K key, Set<V> values); K min(); double percentKeyDataType(DataType type); double proportion(K element); @Override Set<V> put(K key, Set<V> value); @SuppressWarnings("unchecked") @Override Set<V> remove(Object key); double spread(); @Override String toString(); double uniqueness(); VariableType variableType();  }
@Test public void testRemove() { String key = Random.getString(); Set<Integer> value1 = randomValueSet(); Set<Integer> value2 = randomValueSet(); Assert.assertNull(map.remove(key)); map.put(key, value1); Assert.assertEquals(map.remove(key), value1); map.put(key, value2); Assert.assertEquals(map.remove(key), value2); }