001    /*
002     * Copyright (C) 2007 The Guava Authors
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package com.google.common.collect;
018    
019    import static com.google.common.base.Preconditions.checkArgument;
020    import static com.google.common.base.Preconditions.checkNotNull;
021    import static com.google.common.base.Preconditions.checkState;
022    
023    import com.google.common.annotations.Beta;
024    import com.google.common.annotations.GwtCompatible;
025    import com.google.common.annotations.GwtIncompatible;
026    import com.google.common.base.Function;
027    import com.google.common.base.Joiner;
028    import com.google.common.base.Joiner.MapJoiner;
029    import com.google.common.base.Objects;
030    import com.google.common.base.Predicate;
031    import com.google.common.base.Predicates;
032    import com.google.common.base.Supplier;
033    import com.google.common.collect.Collections2.TransformedCollection;
034    import com.google.common.collect.Maps.EntryTransformer;
035    
036    import java.io.IOException;
037    import java.io.ObjectInputStream;
038    import java.io.ObjectOutputStream;
039    import java.io.Serializable;
040    import java.util.AbstractCollection;
041    import java.util.AbstractSet;
042    import java.util.Collection;
043    import java.util.Collections;
044    import java.util.Comparator;
045    import java.util.HashSet;
046    import java.util.Iterator;
047    import java.util.List;
048    import java.util.Map;
049    import java.util.Map.Entry;
050    import java.util.NoSuchElementException;
051    import java.util.Set;
052    import java.util.SortedSet;
053    
054    import javax.annotation.Nullable;
055    
056    /**
057     * Provides static methods acting on or generating a {@code Multimap}.
058     *
059     * <p>See the Guava User Guide article on <a href=
060     * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Multimaps">
061     * {@code Multimaps}</a>.
062     *
063     * @author Jared Levy
064     * @author Robert Konigsberg
065     * @author Mike Bostock
066     * @author Louis Wasserman
067     * @since 2.0 (imported from Google Collections Library)
068     */
069    @GwtCompatible(emulated = true)
070    public final class Multimaps {
071      private Multimaps() {}
072    
073      /**
074       * Creates a new {@code Multimap} that uses the provided map and factory. It
075       * can generate a multimap based on arbitrary {@link Map} and
076       * {@link Collection} classes.
077       *
078       * <p>The {@code factory}-generated and {@code map} classes determine the
079       * multimap iteration order. They also specify the behavior of the
080       * {@code equals}, {@code hashCode}, and {@code toString} methods for the
081       * multimap and its returned views. However, the multimap's {@code get}
082       * method returns instances of a different class than {@code factory.get()}
083       * does.
084       *
085       * <p>The multimap is serializable if {@code map}, {@code factory}, the
086       * collections generated by {@code factory}, and the multimap contents are all
087       * serializable.
088       *
089       * <p>The multimap is not threadsafe when any concurrent operations update the
090       * multimap, even if {@code map} and the instances generated by
091       * {@code factory} are. Concurrent read operations will work correctly. To
092       * allow concurrent update operations, wrap the multimap with a call to
093       * {@link #synchronizedMultimap}.
094       *
095       * <p>Call this method only when the simpler methods
096       * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()},
097       * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()},
098       * {@link TreeMultimap#create()}, and
099       * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
100       *
101       * <p>Note: the multimap assumes complete ownership over of {@code map} and
102       * the collections returned by {@code factory}. Those objects should not be
103       * manually updated and they should not use soft, weak, or phantom references.
104       *
105       * @param map place to store the mapping from each key to its corresponding
106       *     values
107       * @param factory supplier of new, empty collections that will each hold all
108       *     values for a given key
109       * @throws IllegalArgumentException if {@code map} is not empty
110       */
111      public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map,
112          final Supplier<? extends Collection<V>> factory) {
113        return new CustomMultimap<K, V>(map, factory);
114      }
115    
116      private static class CustomMultimap<K, V> extends AbstractMultimap<K, V> {
117        transient Supplier<? extends Collection<V>> factory;
118    
119        CustomMultimap(Map<K, Collection<V>> map,
120            Supplier<? extends Collection<V>> factory) {
121          super(map);
122          this.factory = checkNotNull(factory);
123        }
124    
125        @Override protected Collection<V> createCollection() {
126          return factory.get();
127        }
128    
129        // can't use Serialization writeMultimap and populateMultimap methods since
130        // there's no way to generate the empty backing map.
131    
132        /** @serialData the factory and the backing map */
133        @GwtIncompatible("java.io.ObjectOutputStream")
134        private void writeObject(ObjectOutputStream stream) throws IOException {
135          stream.defaultWriteObject();
136          stream.writeObject(factory);
137          stream.writeObject(backingMap());
138        }
139    
140        @GwtIncompatible("java.io.ObjectInputStream")
141        @SuppressWarnings("unchecked") // reading data stored by writeObject
142        private void readObject(ObjectInputStream stream)
143            throws IOException, ClassNotFoundException {
144          stream.defaultReadObject();
145          factory = (Supplier<? extends Collection<V>>) stream.readObject();
146          Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
147          setMap(map);
148        }
149    
150        @GwtIncompatible("java serialization not supported")
151        private static final long serialVersionUID = 0;
152      }
153    
154      /**
155       * Creates a new {@code ListMultimap} that uses the provided map and factory.
156       * It can generate a multimap based on arbitrary {@link Map} and {@link List}
157       * classes.
158       *
159       * <p>The {@code factory}-generated and {@code map} classes determine the
160       * multimap iteration order. They also specify the behavior of the
161       * {@code equals}, {@code hashCode}, and {@code toString} methods for the
162       * multimap and its returned views. The multimap's {@code get}, {@code
163       * removeAll}, and {@code replaceValues} methods return {@code RandomAccess}
164       * lists if the factory does. However, the multimap's {@code get} method
165       * returns instances of a different class than does {@code factory.get()}.
166       *
167       * <p>The multimap is serializable if {@code map}, {@code factory}, the
168       * lists generated by {@code factory}, and the multimap contents are all
169       * serializable.
170       *
171       * <p>The multimap is not threadsafe when any concurrent operations update the
172       * multimap, even if {@code map} and the instances generated by
173       * {@code factory} are. Concurrent read operations will work correctly. To
174       * allow concurrent update operations, wrap the multimap with a call to
175       * {@link #synchronizedListMultimap}.
176       *
177       * <p>Call this method only when the simpler methods
178       * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()}
179       * won't suffice.
180       *
181       * <p>Note: the multimap assumes complete ownership over of {@code map} and
182       * the lists returned by {@code factory}. Those objects should not be manually
183       * updated, they should be empty when provided, and they should not use soft,
184       * weak, or phantom references.
185       *
186       * @param map place to store the mapping from each key to its corresponding
187       *     values
188       * @param factory supplier of new, empty lists that will each hold all values
189       *     for a given key
190       * @throws IllegalArgumentException if {@code map} is not empty
191       */
192      public static <K, V> ListMultimap<K, V> newListMultimap(
193          Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) {
194        return new CustomListMultimap<K, V>(map, factory);
195      }
196    
197      private static class CustomListMultimap<K, V>
198          extends AbstractListMultimap<K, V> {
199        transient Supplier<? extends List<V>> factory;
200    
201        CustomListMultimap(Map<K, Collection<V>> map,
202            Supplier<? extends List<V>> factory) {
203          super(map);
204          this.factory = checkNotNull(factory);
205        }
206    
207        @Override protected List<V> createCollection() {
208          return factory.get();
209        }
210    
211        /** @serialData the factory and the backing map */
212        @GwtIncompatible("java.io.ObjectOutputStream")
213        private void writeObject(ObjectOutputStream stream) throws IOException {
214          stream.defaultWriteObject();
215          stream.writeObject(factory);
216          stream.writeObject(backingMap());
217        }
218    
219        @GwtIncompatible("java.io.ObjectInputStream")
220        @SuppressWarnings("unchecked") // reading data stored by writeObject
221        private void readObject(ObjectInputStream stream)
222            throws IOException, ClassNotFoundException {
223          stream.defaultReadObject();
224          factory = (Supplier<? extends List<V>>) stream.readObject();
225          Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
226          setMap(map);
227        }
228    
229        @GwtIncompatible("java serialization not supported")
230        private static final long serialVersionUID = 0;
231      }
232    
233      /**
234       * Creates a new {@code SetMultimap} that uses the provided map and factory.
235       * It can generate a multimap based on arbitrary {@link Map} and {@link Set}
236       * classes.
237       *
238       * <p>The {@code factory}-generated and {@code map} classes determine the
239       * multimap iteration order. They also specify the behavior of the
240       * {@code equals}, {@code hashCode}, and {@code toString} methods for the
241       * multimap and its returned views. However, the multimap's {@code get}
242       * method returns instances of a different class than {@code factory.get()}
243       * does.
244       *
245       * <p>The multimap is serializable if {@code map}, {@code factory}, the
246       * sets generated by {@code factory}, and the multimap contents are all
247       * serializable.
248       *
249       * <p>The multimap is not threadsafe when any concurrent operations update the
250       * multimap, even if {@code map} and the instances generated by
251       * {@code factory} are. Concurrent read operations will work correctly. To
252       * allow concurrent update operations, wrap the multimap with a call to
253       * {@link #synchronizedSetMultimap}.
254       *
255       * <p>Call this method only when the simpler methods
256       * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()},
257       * {@link TreeMultimap#create()}, and
258       * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
259       *
260       * <p>Note: the multimap assumes complete ownership over of {@code map} and
261       * the sets returned by {@code factory}. Those objects should not be manually
262       * updated and they should not use soft, weak, or phantom references.
263       *
264       * @param map place to store the mapping from each key to its corresponding
265       *     values
266       * @param factory supplier of new, empty sets that will each hold all values
267       *     for a given key
268       * @throws IllegalArgumentException if {@code map} is not empty
269       */
270      public static <K, V> SetMultimap<K, V> newSetMultimap(
271          Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) {
272        return new CustomSetMultimap<K, V>(map, factory);
273      }
274    
275      private static class CustomSetMultimap<K, V>
276          extends AbstractSetMultimap<K, V> {
277        transient Supplier<? extends Set<V>> factory;
278    
279        CustomSetMultimap(Map<K, Collection<V>> map,
280            Supplier<? extends Set<V>> factory) {
281          super(map);
282          this.factory = checkNotNull(factory);
283        }
284    
285        @Override protected Set<V> createCollection() {
286          return factory.get();
287        }
288    
289        /** @serialData the factory and the backing map */
290        @GwtIncompatible("java.io.ObjectOutputStream")
291        private void writeObject(ObjectOutputStream stream) throws IOException {
292          stream.defaultWriteObject();
293          stream.writeObject(factory);
294          stream.writeObject(backingMap());
295        }
296    
297        @GwtIncompatible("java.io.ObjectInputStream")
298        @SuppressWarnings("unchecked") // reading data stored by writeObject
299        private void readObject(ObjectInputStream stream)
300            throws IOException, ClassNotFoundException {
301          stream.defaultReadObject();
302          factory = (Supplier<? extends Set<V>>) stream.readObject();
303          Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
304          setMap(map);
305        }
306    
307        @GwtIncompatible("not needed in emulated source")
308        private static final long serialVersionUID = 0;
309      }
310    
311      /**
312       * Creates a new {@code SortedSetMultimap} that uses the provided map and
313       * factory. It can generate a multimap based on arbitrary {@link Map} and
314       * {@link SortedSet} classes.
315       *
316       * <p>The {@code factory}-generated and {@code map} classes determine the
317       * multimap iteration order. They also specify the behavior of the
318       * {@code equals}, {@code hashCode}, and {@code toString} methods for the
319       * multimap and its returned views. However, the multimap's {@code get}
320       * method returns instances of a different class than {@code factory.get()}
321       * does.
322       *
323       * <p>The multimap is serializable if {@code map}, {@code factory}, the
324       * sets generated by {@code factory}, and the multimap contents are all
325       * serializable.
326       *
327       * <p>The multimap is not threadsafe when any concurrent operations update the
328       * multimap, even if {@code map} and the instances generated by
329       * {@code factory} are. Concurrent read operations will work correctly. To
330       * allow concurrent update operations, wrap the multimap with a call to
331       * {@link #synchronizedSortedSetMultimap}.
332       *
333       * <p>Call this method only when the simpler methods
334       * {@link TreeMultimap#create()} and
335       * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
336       *
337       * <p>Note: the multimap assumes complete ownership over of {@code map} and
338       * the sets returned by {@code factory}. Those objects should not be manually
339       * updated and they should not use soft, weak, or phantom references.
340       *
341       * @param map place to store the mapping from each key to its corresponding
342       *     values
343       * @param factory supplier of new, empty sorted sets that will each hold
344       *     all values for a given key
345       * @throws IllegalArgumentException if {@code map} is not empty
346       */
347      public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap(
348          Map<K, Collection<V>> map,
349          final Supplier<? extends SortedSet<V>> factory) {
350        return new CustomSortedSetMultimap<K, V>(map, factory);
351      }
352    
353      private static class CustomSortedSetMultimap<K, V>
354          extends AbstractSortedSetMultimap<K, V> {
355        transient Supplier<? extends SortedSet<V>> factory;
356        transient Comparator<? super V> valueComparator;
357    
358        CustomSortedSetMultimap(Map<K, Collection<V>> map,
359            Supplier<? extends SortedSet<V>> factory) {
360          super(map);
361          this.factory = checkNotNull(factory);
362          valueComparator = factory.get().comparator();
363        }
364    
365        @Override protected SortedSet<V> createCollection() {
366          return factory.get();
367        }
368    
369        @Override public Comparator<? super V> valueComparator() {
370          return valueComparator;
371        }
372    
373        /** @serialData the factory and the backing map */
374        @GwtIncompatible("java.io.ObjectOutputStream")
375        private void writeObject(ObjectOutputStream stream) throws IOException {
376          stream.defaultWriteObject();
377          stream.writeObject(factory);
378          stream.writeObject(backingMap());
379        }
380    
381        @GwtIncompatible("java.io.ObjectInputStream")
382        @SuppressWarnings("unchecked") // reading data stored by writeObject
383        private void readObject(ObjectInputStream stream)
384            throws IOException, ClassNotFoundException {
385          stream.defaultReadObject();
386          factory = (Supplier<? extends SortedSet<V>>) stream.readObject();
387          valueComparator = factory.get().comparator();
388          Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
389          setMap(map);
390        }
391    
392        @GwtIncompatible("not needed in emulated source")
393        private static final long serialVersionUID = 0;
394      }
395    
396      /**
397       * Copies each key-value mapping in {@code source} into {@code dest}, with
398       * its key and value reversed.
399       *
400       * <p>If {@code source} is an {@link ImmutableMultimap}, consider using
401       * {@link ImmutableMultimap#inverse} instead.
402       *
403       * @param source any multimap
404       * @param dest the multimap to copy into; usually empty
405       * @return {@code dest}
406       */
407      public static <K, V, M extends Multimap<K, V>> M invertFrom(
408          Multimap<? extends V, ? extends K> source, M dest) {
409        checkNotNull(dest);
410        for (Map.Entry<? extends V, ? extends K> entry : source.entries()) {
411          dest.put(entry.getValue(), entry.getKey());
412        }
413        return dest;
414      }
415    
416      /**
417       * Returns a synchronized (thread-safe) multimap backed by the specified
418       * multimap. In order to guarantee serial access, it is critical that
419       * <b>all</b> access to the backing multimap is accomplished through the
420       * returned multimap.
421       *
422       * <p>It is imperative that the user manually synchronize on the returned
423       * multimap when accessing any of its collection views: <pre>   {@code
424       *
425       *   Multimap<K, V> m = Multimaps.synchronizedMultimap(
426       *       HashMultimap.<K, V>create());
427       *   ...
428       *   Set<K> s = m.keySet();  // Needn't be in synchronized block
429       *   ...
430       *   synchronized (m) {  // Synchronizing on m, not s!
431       *     Iterator<K> i = s.iterator(); // Must be in synchronized block
432       *     while (i.hasNext()) {
433       *       foo(i.next());
434       *     }
435       *   }}</pre>
436       *
437       * Failure to follow this advice may result in non-deterministic behavior.
438       *
439       * <p>Note that the generated multimap's {@link Multimap#removeAll} and
440       * {@link Multimap#replaceValues} methods return collections that aren't
441       * synchronized.
442       *
443       * <p>The returned multimap will be serializable if the specified multimap is
444       * serializable.
445       *
446       * @param multimap the multimap to be wrapped in a synchronized view
447       * @return a synchronized view of the specified multimap
448       */
449      public static <K, V> Multimap<K, V> synchronizedMultimap(
450          Multimap<K, V> multimap) {
451        return Synchronized.multimap(multimap, null);
452      }
453    
454      /**
455       * Returns an unmodifiable view of the specified multimap. Query operations on
456       * the returned multimap "read through" to the specified multimap, and
457       * attempts to modify the returned multimap, either directly or through the
458       * multimap's views, result in an {@code UnsupportedOperationException}.
459       *
460       * <p>Note that the generated multimap's {@link Multimap#removeAll} and
461       * {@link Multimap#replaceValues} methods return collections that are
462       * modifiable.
463       *
464       * <p>The returned multimap will be serializable if the specified multimap is
465       * serializable.
466       *
467       * @param delegate the multimap for which an unmodifiable view is to be
468       *     returned
469       * @return an unmodifiable view of the specified multimap
470       */
471      public static <K, V> Multimap<K, V> unmodifiableMultimap(
472          Multimap<K, V> delegate) {
473        if (delegate instanceof UnmodifiableMultimap ||
474            delegate instanceof ImmutableMultimap) {
475          return delegate;
476        }
477        return new UnmodifiableMultimap<K, V>(delegate);
478      }
479    
480      /**
481       * Simply returns its argument.
482       *
483       * @deprecated no need to use this
484       * @since 10.0
485       */
486      @Deprecated public static <K, V> Multimap<K, V> unmodifiableMultimap(
487          ImmutableMultimap<K, V> delegate) {
488        return checkNotNull(delegate);
489      }
490    
491      private static class UnmodifiableMultimap<K, V>
492          extends ForwardingMultimap<K, V> implements Serializable {
493        final Multimap<K, V> delegate;
494        transient Collection<Entry<K, V>> entries;
495        transient Multiset<K> keys;
496        transient Set<K> keySet;
497        transient Collection<V> values;
498        transient Map<K, Collection<V>> map;
499    
500        UnmodifiableMultimap(final Multimap<K, V> delegate) {
501          this.delegate = checkNotNull(delegate);
502        }
503    
504        @Override protected Multimap<K, V> delegate() {
505          return delegate;
506        }
507    
508        @Override public void clear() {
509          throw new UnsupportedOperationException();
510        }
511    
512        @Override public Map<K, Collection<V>> asMap() {
513          Map<K, Collection<V>> result = map;
514          if (result == null) {
515            final Map<K, Collection<V>> unmodifiableMap
516                = Collections.unmodifiableMap(delegate.asMap());
517            map = result = new ForwardingMap<K, Collection<V>>() {
518              @Override protected Map<K, Collection<V>> delegate() {
519                return unmodifiableMap;
520              }
521    
522              Set<Entry<K, Collection<V>>> entrySet;
523    
524              @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
525                Set<Entry<K, Collection<V>>> result = entrySet;
526                return (result == null)
527                    ? entrySet
528                        = unmodifiableAsMapEntries(unmodifiableMap.entrySet())
529                    : result;
530              }
531    
532              @Override public Collection<V> get(Object key) {
533                Collection<V> collection = unmodifiableMap.get(key);
534                return (collection == null)
535                    ? null : unmodifiableValueCollection(collection);
536              }
537    
538              Collection<Collection<V>> asMapValues;
539    
540              @Override public Collection<Collection<V>> values() {
541                Collection<Collection<V>> result = asMapValues;
542                return (result == null)
543                    ? asMapValues
544                        = new UnmodifiableAsMapValues<V>(unmodifiableMap.values())
545                    : result;
546              }
547    
548              @Override public boolean containsValue(Object o) {
549                return values().contains(o);
550              }
551            };
552          }
553          return result;
554        }
555    
556        @Override public Collection<Entry<K, V>> entries() {
557          Collection<Entry<K, V>> result = entries;
558          if (result == null) {
559            entries = result = unmodifiableEntries(delegate.entries());
560          }
561          return result;
562        }
563    
564        @Override public Collection<V> get(K key) {
565          return unmodifiableValueCollection(delegate.get(key));
566        }
567    
568        @Override public Multiset<K> keys() {
569          Multiset<K> result = keys;
570          if (result == null) {
571            keys = result = Multisets.unmodifiableMultiset(delegate.keys());
572          }
573          return result;
574        }
575    
576        @Override public Set<K> keySet() {
577          Set<K> result = keySet;
578          if (result == null) {
579            keySet = result = Collections.unmodifiableSet(delegate.keySet());
580          }
581          return result;
582        }
583    
584        @Override public boolean put(K key, V value) {
585          throw new UnsupportedOperationException();
586        }
587    
588        @Override public boolean putAll(K key, Iterable<? extends V> values) {
589          throw new UnsupportedOperationException();
590        }
591    
592        @Override
593        public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
594          throw new UnsupportedOperationException();
595        }
596    
597        @Override public boolean remove(Object key, Object value) {
598          throw new UnsupportedOperationException();
599        }
600    
601        @Override public Collection<V> removeAll(Object key) {
602          throw new UnsupportedOperationException();
603        }
604    
605        @Override public Collection<V> replaceValues(
606            K key, Iterable<? extends V> values) {
607          throw new UnsupportedOperationException();
608        }
609    
610        @Override public Collection<V> values() {
611          Collection<V> result = values;
612          if (result == null) {
613            values = result = Collections.unmodifiableCollection(delegate.values());
614          }
615          return result;
616        }
617    
618        private static final long serialVersionUID = 0;
619      }
620    
621      private static class UnmodifiableAsMapValues<V>
622          extends ForwardingCollection<Collection<V>> {
623        final Collection<Collection<V>> delegate;
624        UnmodifiableAsMapValues(Collection<Collection<V>> delegate) {
625          this.delegate = Collections.unmodifiableCollection(delegate);
626        }
627        @Override protected Collection<Collection<V>> delegate() {
628          return delegate;
629        }
630        @Override public Iterator<Collection<V>> iterator() {
631          final Iterator<Collection<V>> iterator = delegate.iterator();
632          return new UnmodifiableIterator<Collection<V>>() {
633            @Override
634            public boolean hasNext() {
635              return iterator.hasNext();
636            }
637            @Override
638            public Collection<V> next() {
639              return unmodifiableValueCollection(iterator.next());
640            }
641          };
642        }
643        @Override public Object[] toArray() {
644          return standardToArray();
645        }
646        @Override public <T> T[] toArray(T[] array) {
647          return standardToArray(array);
648        }
649        @Override public boolean contains(Object o) {
650          return standardContains(o);
651        }
652        @Override public boolean containsAll(Collection<?> c) {
653          return standardContainsAll(c);
654        }
655      }
656    
657      private static class UnmodifiableListMultimap<K, V>
658          extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> {
659        UnmodifiableListMultimap(ListMultimap<K, V> delegate) {
660          super(delegate);
661        }
662        @Override public ListMultimap<K, V> delegate() {
663          return (ListMultimap<K, V>) super.delegate();
664        }
665        @Override public List<V> get(K key) {
666          return Collections.unmodifiableList(delegate().get(key));
667        }
668        @Override public List<V> removeAll(Object key) {
669          throw new UnsupportedOperationException();
670        }
671        @Override public List<V> replaceValues(
672            K key, Iterable<? extends V> values) {
673          throw new UnsupportedOperationException();
674        }
675        private static final long serialVersionUID = 0;
676      }
677    
678      private static class UnmodifiableSetMultimap<K, V>
679          extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> {
680        UnmodifiableSetMultimap(SetMultimap<K, V> delegate) {
681          super(delegate);
682        }
683        @Override public SetMultimap<K, V> delegate() {
684          return (SetMultimap<K, V>) super.delegate();
685        }
686        @Override public Set<V> get(K key) {
687          /*
688           * Note that this doesn't return a SortedSet when delegate is a
689           * SortedSetMultiset, unlike (SortedSet<V>) super.get().
690           */
691          return Collections.unmodifiableSet(delegate().get(key));
692        }
693        @Override public Set<Map.Entry<K, V>> entries() {
694          return Maps.unmodifiableEntrySet(delegate().entries());
695        }
696        @Override public Set<V> removeAll(Object key) {
697          throw new UnsupportedOperationException();
698        }
699        @Override public Set<V> replaceValues(
700            K key, Iterable<? extends V> values) {
701          throw new UnsupportedOperationException();
702        }
703        private static final long serialVersionUID = 0;
704      }
705    
706      private static class UnmodifiableSortedSetMultimap<K, V>
707          extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> {
708        UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) {
709          super(delegate);
710        }
711        @Override public SortedSetMultimap<K, V> delegate() {
712          return (SortedSetMultimap<K, V>) super.delegate();
713        }
714        @Override public SortedSet<V> get(K key) {
715          return Collections.unmodifiableSortedSet(delegate().get(key));
716        }
717        @Override public SortedSet<V> removeAll(Object key) {
718          throw new UnsupportedOperationException();
719        }
720        @Override public SortedSet<V> replaceValues(
721            K key, Iterable<? extends V> values) {
722          throw new UnsupportedOperationException();
723        }
724        @Override
725        public Comparator<? super V> valueComparator() {
726          return delegate().valueComparator();
727        }
728        private static final long serialVersionUID = 0;
729      }
730    
731      /**
732       * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the
733       * specified multimap.
734       *
735       * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
736       *
737       * <p>The returned multimap will be serializable if the specified multimap is
738       * serializable.
739       *
740       * @param multimap the multimap to be wrapped
741       * @return a synchronized view of the specified multimap
742       */
743      public static <K, V> SetMultimap<K, V> synchronizedSetMultimap(
744          SetMultimap<K, V> multimap) {
745        return Synchronized.setMultimap(multimap, null);
746      }
747    
748      /**
749       * Returns an unmodifiable view of the specified {@code SetMultimap}. Query
750       * operations on the returned multimap "read through" to the specified
751       * multimap, and attempts to modify the returned multimap, either directly or
752       * through the multimap's views, result in an
753       * {@code UnsupportedOperationException}.
754       *
755       * <p>Note that the generated multimap's {@link Multimap#removeAll} and
756       * {@link Multimap#replaceValues} methods return collections that are
757       * modifiable.
758       *
759       * <p>The returned multimap will be serializable if the specified multimap is
760       * serializable.
761       *
762       * @param delegate the multimap for which an unmodifiable view is to be
763       *     returned
764       * @return an unmodifiable view of the specified multimap
765       */
766      public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
767          SetMultimap<K, V> delegate) {
768        if (delegate instanceof UnmodifiableSetMultimap ||
769            delegate instanceof ImmutableSetMultimap) {
770          return delegate;
771        }
772        return new UnmodifiableSetMultimap<K, V>(delegate);
773      }
774    
775      /**
776       * Simply returns its argument.
777       *
778       * @deprecated no need to use this
779       * @since 10.0
780       */
781      @Deprecated public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
782          ImmutableSetMultimap<K, V> delegate) {
783        return checkNotNull(delegate);
784      }
785    
786      /**
787       * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by
788       * the specified multimap.
789       *
790       * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
791       *
792       * <p>The returned multimap will be serializable if the specified multimap is
793       * serializable.
794       *
795       * @param multimap the multimap to be wrapped
796       * @return a synchronized view of the specified multimap
797       */
798      public static <K, V> SortedSetMultimap<K, V>
799          synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) {
800        return Synchronized.sortedSetMultimap(multimap, null);
801      }
802    
803      /**
804       * Returns an unmodifiable view of the specified {@code SortedSetMultimap}.
805       * Query operations on the returned multimap "read through" to the specified
806       * multimap, and attempts to modify the returned multimap, either directly or
807       * through the multimap's views, result in an
808       * {@code UnsupportedOperationException}.
809       *
810       * <p>Note that the generated multimap's {@link Multimap#removeAll} and
811       * {@link Multimap#replaceValues} methods return collections that are
812       * modifiable.
813       *
814       * <p>The returned multimap will be serializable if the specified multimap is
815       * serializable.
816       *
817       * @param delegate the multimap for which an unmodifiable view is to be
818       *     returned
819       * @return an unmodifiable view of the specified multimap
820       */
821      public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap(
822          SortedSetMultimap<K, V> delegate) {
823        if (delegate instanceof UnmodifiableSortedSetMultimap) {
824          return delegate;
825        }
826        return new UnmodifiableSortedSetMultimap<K, V>(delegate);
827      }
828    
829      /**
830       * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the
831       * specified multimap.
832       *
833       * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
834       *
835       * @param multimap the multimap to be wrapped
836       * @return a synchronized view of the specified multimap
837       */
838      public static <K, V> ListMultimap<K, V> synchronizedListMultimap(
839          ListMultimap<K, V> multimap) {
840        return Synchronized.listMultimap(multimap, null);
841      }
842    
843      /**
844       * Returns an unmodifiable view of the specified {@code ListMultimap}. Query
845       * operations on the returned multimap "read through" to the specified
846       * multimap, and attempts to modify the returned multimap, either directly or
847       * through the multimap's views, result in an
848       * {@code UnsupportedOperationException}.
849       *
850       * <p>Note that the generated multimap's {@link Multimap#removeAll} and
851       * {@link Multimap#replaceValues} methods return collections that are
852       * modifiable.
853       *
854       * <p>The returned multimap will be serializable if the specified multimap is
855       * serializable.
856       *
857       * @param delegate the multimap for which an unmodifiable view is to be
858       *     returned
859       * @return an unmodifiable view of the specified multimap
860       */
861      public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
862          ListMultimap<K, V> delegate) {
863        if (delegate instanceof UnmodifiableListMultimap ||
864            delegate instanceof ImmutableListMultimap) {
865          return delegate;
866        }
867        return new UnmodifiableListMultimap<K, V>(delegate);
868      }
869    
870      /**
871       * Simply returns its argument.
872       *
873       * @deprecated no need to use this
874       * @since 10.0
875       */
876      @Deprecated public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
877          ImmutableListMultimap<K, V> delegate) {
878        return checkNotNull(delegate);
879      }
880    
881      /**
882       * Returns an unmodifiable view of the specified collection, preserving the
883       * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and
884       * {@code Collection}, in that order of preference.
885       *
886       * @param collection the collection for which to return an unmodifiable view
887       * @return an unmodifiable view of the collection
888       */
889      private static <V> Collection<V> unmodifiableValueCollection(
890          Collection<V> collection) {
891        if (collection instanceof SortedSet) {
892          return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
893        } else if (collection instanceof Set) {
894          return Collections.unmodifiableSet((Set<V>) collection);
895        } else if (collection instanceof List) {
896          return Collections.unmodifiableList((List<V>) collection);
897        }
898        return Collections.unmodifiableCollection(collection);
899      }
900    
901      /**
902       * Returns an unmodifiable view of the specified multimap {@code asMap} entry.
903       * The {@link Entry#setValue} operation throws an {@link
904       * UnsupportedOperationException}, and the collection returned by {@code
905       * getValue} is also an unmodifiable (type-preserving) view. This also has the
906       * side-effect of redefining equals to comply with the Map.Entry contract, and
907       * to avoid a possible nefarious implementation of equals.
908       *
909       * @param entry the entry for which to return an unmodifiable view
910       * @return an unmodifiable view of the entry
911       */
912      private static <K, V> Map.Entry<K, Collection<V>> unmodifiableAsMapEntry(
913          final Map.Entry<K, Collection<V>> entry) {
914        checkNotNull(entry);
915        return new AbstractMapEntry<K, Collection<V>>() {
916          @Override public K getKey() {
917            return entry.getKey();
918          }
919    
920          @Override public Collection<V> getValue() {
921            return unmodifiableValueCollection(entry.getValue());
922          }
923        };
924      }
925    
926      /**
927       * Returns an unmodifiable view of the specified collection of entries. The
928       * {@link Entry#setValue} operation throws an {@link
929       * UnsupportedOperationException}. If the specified collection is a {@code
930       * Set}, the returned collection is also a {@code Set}.
931       *
932       * @param entries the entries for which to return an unmodifiable view
933       * @return an unmodifiable view of the entries
934       */
935      private static <K, V> Collection<Entry<K, V>> unmodifiableEntries(
936          Collection<Entry<K, V>> entries) {
937        if (entries instanceof Set) {
938          return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries);
939        }
940        return new Maps.UnmodifiableEntries<K, V>(
941            Collections.unmodifiableCollection(entries));
942      }
943    
944      /**
945       * Returns an unmodifiable view of the specified set of {@code asMap} entries.
946       * The {@link Entry#setValue} operation throws an {@link
947       * UnsupportedOperationException}, as do any operations that attempt to modify
948       * the returned collection.
949       *
950       * @param asMapEntries the {@code asMap} entries for which to return an
951       *     unmodifiable view
952       * @return an unmodifiable view of the collection entries
953       */
954      private static <K, V> Set<Entry<K, Collection<V>>> unmodifiableAsMapEntries(
955          Set<Entry<K, Collection<V>>> asMapEntries) {
956        return new UnmodifiableAsMapEntries<K, V>(
957            Collections.unmodifiableSet(asMapEntries));
958      }
959    
960      /** @see Multimaps#unmodifiableAsMapEntries */
961      static class UnmodifiableAsMapEntries<K, V>
962          extends ForwardingSet<Entry<K, Collection<V>>> {
963        private final Set<Entry<K, Collection<V>>> delegate;
964        UnmodifiableAsMapEntries(Set<Entry<K, Collection<V>>> delegate) {
965          this.delegate = delegate;
966        }
967    
968        @Override protected Set<Entry<K, Collection<V>>> delegate() {
969          return delegate;
970        }
971    
972        @Override public Iterator<Entry<K, Collection<V>>> iterator() {
973          final Iterator<Entry<K, Collection<V>>> iterator = delegate.iterator();
974          return new ForwardingIterator<Entry<K, Collection<V>>>() {
975            @Override protected Iterator<Entry<K, Collection<V>>> delegate() {
976              return iterator;
977            }
978            @Override public Entry<K, Collection<V>> next() {
979              return unmodifiableAsMapEntry(iterator.next());
980            }
981          };
982        }
983    
984        @Override public Object[] toArray() {
985          return standardToArray();
986        }
987    
988        @Override public <T> T[] toArray(T[] array) {
989          return standardToArray(array);
990        }
991    
992        @Override public boolean contains(Object o) {
993          return Maps.containsEntryImpl(delegate(), o);
994        }
995    
996        @Override public boolean containsAll(Collection<?> c) {
997          return standardContainsAll(c);
998        }
999    
1000        @Override public boolean equals(@Nullable Object object) {
1001          return standardEquals(object);
1002        }
1003      }
1004    
1005      /**
1006       * Returns a multimap view of the specified map. The multimap is backed by the
1007       * map, so changes to the map are reflected in the multimap, and vice versa.
1008       * If the map is modified while an iteration over one of the multimap's
1009       * collection views is in progress (except through the iterator's own {@code
1010       * remove} operation, or through the {@code setValue} operation on a map entry
1011       * returned by the iterator), the results of the iteration are undefined.
1012       *
1013       * <p>The multimap supports mapping removal, which removes the corresponding
1014       * mapping from the map. It does not support any operations which might add
1015       * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}.
1016       *
1017       * <p>The returned multimap will be serializable if the specified map is
1018       * serializable.
1019       *
1020       * @param map the backing map for the returned multimap view
1021       */
1022      public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) {
1023        return new MapMultimap<K, V>(map);
1024      }
1025    
1026      /** @see Multimaps#forMap */
1027      private static class MapMultimap<K, V>
1028          implements SetMultimap<K, V>, Serializable {
1029        final Map<K, V> map;
1030        transient Map<K, Collection<V>> asMap;
1031    
1032        MapMultimap(Map<K, V> map) {
1033          this.map = checkNotNull(map);
1034        }
1035    
1036        @Override
1037        public int size() {
1038          return map.size();
1039        }
1040    
1041        @Override
1042        public boolean isEmpty() {
1043          return map.isEmpty();
1044        }
1045    
1046        @Override
1047        public boolean containsKey(Object key) {
1048          return map.containsKey(key);
1049        }
1050    
1051        @Override
1052        public boolean containsValue(Object value) {
1053          return map.containsValue(value);
1054        }
1055    
1056        @Override
1057        public boolean containsEntry(Object key, Object value) {
1058          return map.entrySet().contains(Maps.immutableEntry(key, value));
1059        }
1060    
1061        @Override
1062        public Set<V> get(final K key) {
1063          return new AbstractSet<V>() {
1064            @Override public Iterator<V> iterator() {
1065              return new Iterator<V>() {
1066                int i;
1067    
1068                @Override
1069                public boolean hasNext() {
1070                  return (i == 0) && map.containsKey(key);
1071                }
1072    
1073                @Override
1074                public V next() {
1075                  if (!hasNext()) {
1076                    throw new NoSuchElementException();
1077                  }
1078                  i++;
1079                  return map.get(key);
1080                }
1081    
1082                @Override
1083                public void remove() {
1084                  checkState(i == 1);
1085                  i = -1;
1086                  map.remove(key);
1087                }
1088              };
1089            }
1090    
1091            @Override public int size() {
1092              return map.containsKey(key) ? 1 : 0;
1093            }
1094          };
1095        }
1096    
1097        @Override
1098        public boolean put(K key, V value) {
1099          throw new UnsupportedOperationException();
1100        }
1101    
1102        @Override
1103        public boolean putAll(K key, Iterable<? extends V> values) {
1104          throw new UnsupportedOperationException();
1105        }
1106    
1107        @Override
1108        public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
1109          throw new UnsupportedOperationException();
1110        }
1111    
1112        @Override
1113        public Set<V> replaceValues(K key, Iterable<? extends V> values) {
1114          throw new UnsupportedOperationException();
1115        }
1116    
1117        @Override
1118        public boolean remove(Object key, Object value) {
1119          return map.entrySet().remove(Maps.immutableEntry(key, value));
1120        }
1121    
1122        @Override
1123        public Set<V> removeAll(Object key) {
1124          Set<V> values = new HashSet<V>(2);
1125          if (!map.containsKey(key)) {
1126            return values;
1127          }
1128          values.add(map.remove(key));
1129          return values;
1130        }
1131    
1132        @Override
1133        public void clear() {
1134          map.clear();
1135        }
1136    
1137        @Override
1138        public Set<K> keySet() {
1139          return map.keySet();
1140        }
1141    
1142        @Override
1143        public Multiset<K> keys() {
1144          return Multisets.forSet(map.keySet());
1145        }
1146    
1147        @Override
1148        public Collection<V> values() {
1149          return map.values();
1150        }
1151    
1152        @Override
1153        public Set<Entry<K, V>> entries() {
1154          return map.entrySet();
1155        }
1156    
1157        @Override
1158        public Map<K, Collection<V>> asMap() {
1159          Map<K, Collection<V>> result = asMap;
1160          if (result == null) {
1161            asMap = result = new AsMap();
1162          }
1163          return result;
1164        }
1165    
1166        @Override public boolean equals(@Nullable Object object) {
1167          if (object == this) {
1168            return true;
1169          }
1170          if (object instanceof Multimap) {
1171            Multimap<?, ?> that = (Multimap<?, ?>) object;
1172            return this.size() == that.size() && asMap().equals(that.asMap());
1173          }
1174          return false;
1175        }
1176    
1177        @Override public int hashCode() {
1178          return map.hashCode();
1179        }
1180    
1181        private static final MapJoiner JOINER
1182            = Joiner.on("], ").withKeyValueSeparator("=[").useForNull("null");
1183    
1184        @Override public String toString() {
1185          if (map.isEmpty()) {
1186            return "{}";
1187          }
1188          StringBuilder builder
1189              = Collections2.newStringBuilderForCollection(map.size()).append('{');
1190          JOINER.appendTo(builder, map);
1191          return builder.append("]}").toString();
1192        }
1193    
1194        /** @see MapMultimap#asMap */
1195        class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
1196          @Override public int size() {
1197            return map.size();
1198          }
1199    
1200          @Override public Iterator<Entry<K, Collection<V>>> iterator() {
1201            return new TransformedIterator<K, Entry<K, Collection<V>>>(map.keySet().iterator()) {
1202              @Override
1203              Entry<K, Collection<V>> transform(final K key) {
1204                return new AbstractMapEntry<K, Collection<V>>() {
1205                  @Override
1206                  public K getKey() {
1207                    return key;
1208                  }
1209    
1210                  @Override
1211                  public Collection<V> getValue() {
1212                    return get(key);
1213                  }
1214                };
1215              }
1216            };
1217          }
1218    
1219          @Override public boolean contains(Object o) {
1220            if (!(o instanceof Entry)) {
1221              return false;
1222            }
1223            Entry<?, ?> entry = (Entry<?, ?>) o;
1224            if (!(entry.getValue() instanceof Set)) {
1225              return false;
1226            }
1227            Set<?> set = (Set<?>) entry.getValue();
1228            return (set.size() == 1)
1229                && containsEntry(entry.getKey(), set.iterator().next());
1230          }
1231    
1232          @Override public boolean remove(Object o) {
1233            if (!(o instanceof Entry)) {
1234              return false;
1235            }
1236            Entry<?, ?> entry = (Entry<?, ?>) o;
1237            if (!(entry.getValue() instanceof Set)) {
1238              return false;
1239            }
1240            Set<?> set = (Set<?>) entry.getValue();
1241            return (set.size() == 1)
1242                && map.entrySet().remove(
1243                    Maps.immutableEntry(entry.getKey(), set.iterator().next()));
1244          }
1245        }
1246    
1247        /** @see MapMultimap#asMap */
1248        class AsMap extends Maps.ImprovedAbstractMap<K, Collection<V>> {
1249          @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
1250            return new AsMapEntries();
1251          }
1252    
1253          // The following methods are included for performance.
1254    
1255          @Override public boolean containsKey(Object key) {
1256            return map.containsKey(key);
1257          }
1258    
1259          @SuppressWarnings("unchecked")
1260          @Override public Collection<V> get(Object key) {
1261            Collection<V> collection = MapMultimap.this.get((K) key);
1262            return collection.isEmpty() ? null : collection;
1263          }
1264    
1265          @Override public Collection<V> remove(Object key) {
1266            Collection<V> collection = removeAll(key);
1267            return collection.isEmpty() ? null : collection;
1268          }
1269        }
1270        private static final long serialVersionUID = 7845222491160860175L;
1271      }
1272    
1273      /**
1274       * Returns a view of a multimap where each value is transformed by a function.
1275       * All other properties of the multimap, such as iteration order, are left
1276       * intact. For example, the code: <pre>   {@code
1277       *
1278       * Multimap<String, Integer> multimap =
1279       *     ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6);
1280       * Function<Integer, String> square = new Function<Integer, String>() {
1281       *     public String apply(Integer in) {
1282       *       return Integer.toString(in * in);
1283       *     }
1284       * };
1285       * Multimap<String, String> transformed =
1286       *     Multimaps.transformValues(multimap, square);
1287       *   System.out.println(transformed);}</pre>
1288       *
1289       * ... prints {@code {a=[4, 16], b=[9, 9], c=[6]}}.
1290       *
1291       * <p>Changes in the underlying multimap are reflected in this view.
1292       * Conversely, this view supports removal operations, and these are reflected
1293       * in the underlying multimap.
1294       *
1295       * <p>It's acceptable for the underlying multimap to contain null keys, and
1296       * even null values provided that the function is capable of accepting null
1297       * input.  The transformed multimap might contain null values, if the function
1298       * sometimes gives a null result.
1299       *
1300       * <p>The returned multimap is not thread-safe or serializable, even if the
1301       * underlying multimap is.  The {@code equals} and {@code hashCode} methods
1302       * of the returned multimap are meaningless, since there is not a definition
1303       * of {@code equals} or {@code hashCode} for general collections, and
1304       * {@code get()} will return a general {@code Collection} as opposed to a
1305       * {@code List} or a {@code Set}.
1306       *
1307       * <p>The function is applied lazily, invoked when needed. This is necessary
1308       * for the returned multimap to be a view, but it means that the function will
1309       * be applied many times for bulk operations like
1310       * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1311       * perform well, {@code function} should be fast. To avoid lazy evaluation
1312       * when the returned multimap doesn't need to be a view, copy the returned
1313       * multimap into a new multimap of your choosing.
1314       *
1315       * @since 7.0
1316       */
1317      public static <K, V1, V2> Multimap<K, V2> transformValues(
1318          Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
1319        checkNotNull(function);
1320        EntryTransformer<K, V1, V2> transformer =
1321            new EntryTransformer<K, V1, V2>() {
1322              @Override
1323              public V2 transformEntry(K key, V1 value) {
1324                return function.apply(value);
1325              }
1326            };
1327        return transformEntries(fromMultimap, transformer);
1328      }
1329    
1330      /**
1331       * Returns a view of a multimap whose values are derived from the original
1332       * multimap's entries. In contrast to {@link #transformValues}, this method's
1333       * entry-transformation logic may depend on the key as well as the value.
1334       *
1335       * <p>All other properties of the transformed multimap, such as iteration
1336       * order, are left intact. For example, the code: <pre>   {@code
1337       *
1338       *   SetMultimap<String, Integer> multimap =
1339       *       ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
1340       *   EntryTransformer<String, Integer, String> transformer =
1341       *       new EntryTransformer<String, Integer, String>() {
1342       *         public String transformEntry(String key, Integer value) {
1343       *            return (value >= 0) ? key : "no" + key;
1344       *         }
1345       *       };
1346       *   Multimap<String, String> transformed =
1347       *       Multimaps.transformEntries(multimap, transformer);
1348       *   System.out.println(transformed);}</pre>
1349       *
1350       * ... prints {@code {a=[a, a], b=[nob]}}.
1351       *
1352       * <p>Changes in the underlying multimap are reflected in this view.
1353       * Conversely, this view supports removal operations, and these are reflected
1354       * in the underlying multimap.
1355       *
1356       * <p>It's acceptable for the underlying multimap to contain null keys and
1357       * null values provided that the transformer is capable of accepting null
1358       * inputs. The transformed multimap might contain null values if the
1359       * transformer sometimes gives a null result.
1360       *
1361       * <p>The returned multimap is not thread-safe or serializable, even if the
1362       * underlying multimap is.  The {@code equals} and {@code hashCode} methods
1363       * of the returned multimap are meaningless, since there is not a definition
1364       * of {@code equals} or {@code hashCode} for general collections, and
1365       * {@code get()} will return a general {@code Collection} as opposed to a
1366       * {@code List} or a {@code Set}.
1367       *
1368       * <p>The transformer is applied lazily, invoked when needed. This is
1369       * necessary for the returned multimap to be a view, but it means that the
1370       * transformer will be applied many times for bulk operations like {@link
1371       * Multimap#containsValue} and {@link Object#toString}. For this to perform
1372       * well, {@code transformer} should be fast. To avoid lazy evaluation when the
1373       * returned multimap doesn't need to be a view, copy the returned multimap
1374       * into a new multimap of your choosing.
1375       *
1376       * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1377       * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1378       * that {@code k2} is also of type {@code K}. Using an {@code
1379       * EntryTransformer} key type for which this may not hold, such as {@code
1380       * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1381       * the transformed multimap.
1382       *
1383       * @since 7.0
1384       */
1385      public static <K, V1, V2> Multimap<K, V2> transformEntries(
1386          Multimap<K, V1> fromMap,
1387          EntryTransformer<? super K, ? super V1, V2> transformer) {
1388        return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer);
1389      }
1390    
1391      private static class TransformedEntriesMultimap<K, V1, V2>
1392          implements Multimap<K, V2> {
1393        final Multimap<K, V1> fromMultimap;
1394        final EntryTransformer<? super K, ? super V1, V2> transformer;
1395    
1396        TransformedEntriesMultimap(Multimap<K, V1> fromMultimap,
1397            final EntryTransformer<? super K, ? super V1, V2> transformer) {
1398          this.fromMultimap = checkNotNull(fromMultimap);
1399          this.transformer = checkNotNull(transformer);
1400        }
1401    
1402        Collection<V2> transform(final K key, Collection<V1> values) {
1403          return Collections2.transform(values, new Function<V1, V2>() {
1404            @Override public V2 apply(V1 value) {
1405              return transformer.transformEntry(key, value);
1406            }
1407          });
1408        }
1409    
1410        private transient Map<K, Collection<V2>> asMap;
1411    
1412        @Override public Map<K, Collection<V2>> asMap() {
1413          if (asMap == null) {
1414            Map<K, Collection<V2>> aM = Maps.transformEntries(fromMultimap.asMap(),
1415                new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
1416    
1417                  @Override public Collection<V2> transformEntry(
1418                      K key, Collection<V1> value) {
1419                    return transform(key, value);
1420                  }
1421                });
1422            asMap = aM;
1423            return aM;
1424          }
1425          return asMap;
1426        }
1427    
1428        @Override public void clear() {
1429          fromMultimap.clear();
1430        }
1431    
1432        @SuppressWarnings("unchecked")
1433        @Override public boolean containsEntry(Object key, Object value) {
1434          Collection<V2> values = get((K) key);
1435          return values.contains(value);
1436        }
1437    
1438        @Override public boolean containsKey(Object key) {
1439          return fromMultimap.containsKey(key);
1440        }
1441    
1442        @Override public boolean containsValue(Object value) {
1443          return values().contains(value);
1444        }
1445    
1446        private transient Collection<Entry<K, V2>> entries;
1447    
1448        @Override public Collection<Entry<K, V2>> entries() {
1449          if (entries == null) {
1450            Collection<Entry<K, V2>> es = new TransformedEntries(transformer);
1451            entries = es;
1452            return es;
1453          }
1454          return entries;
1455        }
1456    
1457        private class TransformedEntries
1458            extends TransformedCollection<Entry<K, V1>, Entry<K, V2>> {
1459    
1460          TransformedEntries(
1461              final EntryTransformer<? super K, ? super V1, V2> transformer) {
1462            super(fromMultimap.entries(),
1463                new Function<Entry<K, V1>, Entry<K, V2>>() {
1464                  @Override public Entry<K, V2> apply(final Entry<K, V1> entry) {
1465                    return new AbstractMapEntry<K, V2>() {
1466    
1467                      @Override public K getKey() {
1468                        return entry.getKey();
1469                      }
1470    
1471                      @Override public V2 getValue() {
1472                        return transformer.transformEntry(
1473                            entry.getKey(), entry.getValue());
1474                      }
1475                    };
1476                  }
1477                });
1478          }
1479    
1480          @Override public boolean contains(Object o) {
1481            if (o instanceof Entry) {
1482              Entry<?, ?> entry = (Entry<?, ?>) o;
1483              return containsEntry(entry.getKey(), entry.getValue());
1484            }
1485            return false;
1486          }
1487    
1488          @SuppressWarnings("unchecked")
1489          @Override public boolean remove(Object o) {
1490            if (o instanceof Entry) {
1491              Entry<?, ?> entry = (Entry<?, ?>) o;
1492              Collection<V2> values = get((K) entry.getKey());
1493              return values.remove(entry.getValue());
1494            }
1495            return false;
1496          }
1497    
1498        }
1499    
1500        @Override public Collection<V2> get(final K key) {
1501          return transform(key, fromMultimap.get(key));
1502        }
1503    
1504        @Override public boolean isEmpty() {
1505          return fromMultimap.isEmpty();
1506        }
1507    
1508        @Override public Set<K> keySet() {
1509          return fromMultimap.keySet();
1510        }
1511    
1512        @Override public Multiset<K> keys() {
1513          return fromMultimap.keys();
1514        }
1515    
1516        @Override public boolean put(K key, V2 value) {
1517          throw new UnsupportedOperationException();
1518        }
1519    
1520        @Override public boolean putAll(K key, Iterable<? extends V2> values) {
1521          throw new UnsupportedOperationException();
1522        }
1523    
1524        @Override public boolean putAll(
1525            Multimap<? extends K, ? extends V2> multimap) {
1526          throw new UnsupportedOperationException();
1527        }
1528    
1529        @SuppressWarnings("unchecked")
1530        @Override public boolean remove(Object key, Object value) {
1531          return get((K) key).remove(value);
1532        }
1533    
1534        @SuppressWarnings("unchecked")
1535        @Override public Collection<V2> removeAll(Object key) {
1536          return transform((K) key, fromMultimap.removeAll(key));
1537        }
1538    
1539        @Override public Collection<V2> replaceValues(
1540            K key, Iterable<? extends V2> values) {
1541          throw new UnsupportedOperationException();
1542        }
1543    
1544        @Override public int size() {
1545          return fromMultimap.size();
1546        }
1547    
1548        private transient Collection<V2> values;
1549    
1550        @Override public Collection<V2> values() {
1551          if (values == null) {
1552            Collection<V2> vs = Collections2.transform(
1553                fromMultimap.entries(), new Function<Entry<K, V1>, V2>() {
1554    
1555                  @Override public V2 apply(Entry<K, V1> entry) {
1556                    return transformer.transformEntry(
1557                        entry.getKey(), entry.getValue());
1558                  }
1559                });
1560            values = vs;
1561            return vs;
1562          }
1563          return values;
1564        }
1565    
1566        @Override public boolean equals(Object obj) {
1567          if (obj instanceof Multimap) {
1568            Multimap<?, ?> other = (Multimap<?, ?>) obj;
1569            return asMap().equals(other.asMap());
1570          }
1571          return false;
1572        }
1573    
1574        @Override public int hashCode() {
1575          return asMap().hashCode();
1576        }
1577    
1578        @Override public String toString() {
1579          return asMap().toString();
1580        }
1581      }
1582    
1583      /**
1584       * Returns a view of a {@code ListMultimap} where each value is transformed by
1585       * a function. All other properties of the multimap, such as iteration order,
1586       * are left intact. For example, the code: <pre>   {@code
1587       *
1588       *   ListMultimap<String, Integer> multimap
1589       *        = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9);
1590       *   Function<Integer, Double> sqrt =
1591       *       new Function<Integer, Double>() {
1592       *         public Double apply(Integer in) {
1593       *           return Math.sqrt((int) in);
1594       *         }
1595       *       };
1596       *   ListMultimap<String, Double> transformed = Multimaps.transformValues(map,
1597       *       sqrt);
1598       *   System.out.println(transformed);}</pre>
1599       *
1600       * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}.
1601       *
1602       * <p>Changes in the underlying multimap are reflected in this view.
1603       * Conversely, this view supports removal operations, and these are reflected
1604       * in the underlying multimap.
1605       *
1606       * <p>It's acceptable for the underlying multimap to contain null keys, and
1607       * even null values provided that the function is capable of accepting null
1608       * input.  The transformed multimap might contain null values, if the function
1609       * sometimes gives a null result.
1610       *
1611       * <p>The returned multimap is not thread-safe or serializable, even if the
1612       * underlying multimap is.
1613       *
1614       * <p>The function is applied lazily, invoked when needed. This is necessary
1615       * for the returned multimap to be a view, but it means that the function will
1616       * be applied many times for bulk operations like
1617       * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1618       * perform well, {@code function} should be fast. To avoid lazy evaluation
1619       * when the returned multimap doesn't need to be a view, copy the returned
1620       * multimap into a new multimap of your choosing.
1621       *
1622       * @since 7.0
1623       */
1624      public static <K, V1, V2> ListMultimap<K, V2> transformValues(
1625          ListMultimap<K, V1> fromMultimap,
1626          final Function<? super V1, V2> function) {
1627        checkNotNull(function);
1628        EntryTransformer<K, V1, V2> transformer =
1629            new EntryTransformer<K, V1, V2>() {
1630              @Override
1631              public V2 transformEntry(K key, V1 value) {
1632                return function.apply(value);
1633              }
1634            };
1635        return transformEntries(fromMultimap, transformer);
1636      }
1637    
1638      /**
1639       * Returns a view of a {@code ListMultimap} whose values are derived from the
1640       * original multimap's entries. In contrast to
1641       * {@link #transformValues(ListMultimap, Function)}, this method's
1642       * entry-transformation logic may depend on the key as well as the value.
1643       *
1644       * <p>All other properties of the transformed multimap, such as iteration
1645       * order, are left intact. For example, the code: <pre>   {@code
1646       *
1647       *   Multimap<String, Integer> multimap =
1648       *       ImmutableMultimap.of("a", 1, "a", 4, "b", 6);
1649       *   EntryTransformer<String, Integer, String> transformer =
1650       *       new EntryTransformer<String, Integer, String>() {
1651       *         public String transformEntry(String key, Integer value) {
1652       *           return key + value;
1653       *         }
1654       *       };
1655       *   Multimap<String, String> transformed =
1656       *       Multimaps.transformEntries(multimap, transformer);
1657       *   System.out.println(transformed);}</pre>
1658       *
1659       * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}.
1660       *
1661       * <p>Changes in the underlying multimap are reflected in this view.
1662       * Conversely, this view supports removal operations, and these are reflected
1663       * in the underlying multimap.
1664       *
1665       * <p>It's acceptable for the underlying multimap to contain null keys and
1666       * null values provided that the transformer is capable of accepting null
1667       * inputs. The transformed multimap might contain null values if the
1668       * transformer sometimes gives a null result.
1669       *
1670       * <p>The returned multimap is not thread-safe or serializable, even if the
1671       * underlying multimap is.
1672       *
1673       * <p>The transformer is applied lazily, invoked when needed. This is
1674       * necessary for the returned multimap to be a view, but it means that the
1675       * transformer will be applied many times for bulk operations like {@link
1676       * Multimap#containsValue} and {@link Object#toString}. For this to perform
1677       * well, {@code transformer} should be fast. To avoid lazy evaluation when the
1678       * returned multimap doesn't need to be a view, copy the returned multimap
1679       * into a new multimap of your choosing.
1680       *
1681       * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1682       * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1683       * that {@code k2} is also of type {@code K}. Using an {@code
1684       * EntryTransformer} key type for which this may not hold, such as {@code
1685       * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1686       * the transformed multimap.
1687       *
1688       * @since 7.0
1689       */
1690      public static <K, V1, V2> ListMultimap<K, V2> transformEntries(
1691          ListMultimap<K, V1> fromMap,
1692          EntryTransformer<? super K, ? super V1, V2> transformer) {
1693        return new TransformedEntriesListMultimap<K, V1, V2>(fromMap, transformer);
1694      }
1695    
1696      private static final class TransformedEntriesListMultimap<K, V1, V2>
1697          extends TransformedEntriesMultimap<K, V1, V2>
1698          implements ListMultimap<K, V2> {
1699    
1700        TransformedEntriesListMultimap(ListMultimap<K, V1> fromMultimap,
1701            EntryTransformer<? super K, ? super V1, V2> transformer) {
1702          super(fromMultimap, transformer);
1703        }
1704    
1705        @Override List<V2> transform(final K key, Collection<V1> values) {
1706          return Lists.transform((List<V1>) values, new Function<V1, V2>() {
1707            @Override public V2 apply(V1 value) {
1708              return transformer.transformEntry(key, value);
1709            }
1710          });
1711        }
1712    
1713        @Override public List<V2> get(K key) {
1714          return transform(key, fromMultimap.get(key));
1715        }
1716    
1717        @SuppressWarnings("unchecked")
1718        @Override public List<V2> removeAll(Object key) {
1719          return transform((K) key, fromMultimap.removeAll(key));
1720        }
1721    
1722        @Override public List<V2> replaceValues(
1723            K key, Iterable<? extends V2> values) {
1724          throw new UnsupportedOperationException();
1725        }
1726      }
1727    
1728      /**
1729       * Creates an index {@code ImmutableListMultimap} that contains the results of
1730       * applying a specified function to each item in an {@code Iterable} of
1731       * values. Each value will be stored as a value in the resulting multimap,
1732       * yielding a multimap with the same size as the input iterable. The key used
1733       * to store that value in the multimap will be the result of calling the
1734       * function on that value. The resulting multimap is created as an immutable
1735       * snapshot. In the returned multimap, keys appear in the order they are first
1736       * encountered, and the values corresponding to each key appear in the same
1737       * order as they are encountered.
1738       *
1739       * <p>For example, <pre>   {@code
1740       *
1741       *   List<String> badGuys =
1742       *       Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1743       *   Function<String, Integer> stringLengthFunction = ...;
1744       *   Multimap<Integer, String> index =
1745       *       Multimaps.index(badGuys, stringLengthFunction);
1746       *   System.out.println(index);}</pre>
1747       *
1748       * prints <pre>   {@code
1749       *
1750       *   {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
1751       *
1752       * The returned multimap is serializable if its keys and values are all
1753       * serializable.
1754       *
1755       * @param values the values to use when constructing the {@code
1756       *     ImmutableListMultimap}
1757       * @param keyFunction the function used to produce the key for each value
1758       * @return {@code ImmutableListMultimap} mapping the result of evaluating the
1759       *     function {@code keyFunction} on each value in the input collection to
1760       *     that value
1761       * @throws NullPointerException if any of the following cases is true:
1762       *     <ul>
1763       *     <li>{@code values} is null
1764       *     <li>{@code keyFunction} is null
1765       *     <li>An element in {@code values} is null
1766       *     <li>{@code keyFunction} returns {@code null} for any element of {@code
1767       *         values}
1768       *     </ul>
1769       */
1770      public static <K, V> ImmutableListMultimap<K, V> index(
1771          Iterable<V> values, Function<? super V, K> keyFunction) {
1772        return index(values.iterator(), keyFunction);
1773      }
1774    
1775      /**
1776       * Creates an index {@code ImmutableListMultimap} that contains the results of
1777       * applying a specified function to each item in an {@code Iterator} of
1778       * values. Each value will be stored as a value in the resulting multimap,
1779       * yielding a multimap with the same size as the input iterator. The key used
1780       * to store that value in the multimap will be the result of calling the
1781       * function on that value. The resulting multimap is created as an immutable
1782       * snapshot. In the returned multimap, keys appear in the order they are first
1783       * encountered, and the values corresponding to each key appear in the same
1784       * order as they are encountered.
1785       *
1786       * <p>For example, <pre>   {@code
1787       *
1788       *   List<String> badGuys =
1789       *       Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1790       *   Function<String, Integer> stringLengthFunction = ...;
1791       *   Multimap<Integer, String> index =
1792       *       Multimaps.index(badGuys.iterator(), stringLengthFunction);
1793       *   System.out.println(index);}</pre>
1794       *
1795       * prints <pre>   {@code
1796       *
1797       *   {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
1798       *
1799       * The returned multimap is serializable if its keys and values are all
1800       * serializable.
1801       *
1802       * @param values the values to use when constructing the {@code
1803       *     ImmutableListMultimap}
1804       * @param keyFunction the function used to produce the key for each value
1805       * @return {@code ImmutableListMultimap} mapping the result of evaluating the
1806       *     function {@code keyFunction} on each value in the input collection to
1807       *     that value
1808       * @throws NullPointerException if any of the following cases is true:
1809       *     <ul>
1810       *     <li>{@code values} is null
1811       *     <li>{@code keyFunction} is null
1812       *     <li>An element in {@code values} is null
1813       *     <li>{@code keyFunction} returns {@code null} for any element of {@code
1814       *         values}
1815       *     </ul>
1816       * @since 10.0
1817       */
1818      public static <K, V> ImmutableListMultimap<K, V> index(
1819          Iterator<V> values, Function<? super V, K> keyFunction) {
1820        checkNotNull(keyFunction);
1821        ImmutableListMultimap.Builder<K, V> builder
1822            = ImmutableListMultimap.builder();
1823        while (values.hasNext()) {
1824          V value = values.next();
1825          checkNotNull(value, values);
1826          builder.put(keyFunction.apply(value), value);
1827        }
1828        return builder.build();
1829      }
1830    
1831      static abstract class Keys<K, V> extends AbstractMultiset<K> {
1832        abstract Multimap<K, V> multimap();
1833    
1834        @Override Iterator<Multiset.Entry<K>> entryIterator() {
1835          return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>(
1836              multimap().asMap().entrySet().iterator()) {
1837            @Override
1838            Multiset.Entry<K> transform(
1839                final Map.Entry<K, Collection<V>> backingEntry) {
1840              return new Multisets.AbstractEntry<K>() {
1841                @Override
1842                public K getElement() {
1843                  return backingEntry.getKey();
1844                }
1845    
1846                @Override
1847                public int getCount() {
1848                  return backingEntry.getValue().size();
1849                }
1850              };
1851            }
1852          };
1853        }
1854    
1855        @Override int distinctElements() {
1856          return multimap().asMap().size();
1857        }
1858    
1859        @Override Set<Multiset.Entry<K>> createEntrySet() {
1860          return new KeysEntrySet();
1861        }
1862    
1863        class KeysEntrySet extends Multisets.EntrySet<K> {
1864          @Override Multiset<K> multiset() {
1865            return Keys.this;
1866          }
1867    
1868          @Override public Iterator<Multiset.Entry<K>> iterator() {
1869            return entryIterator();
1870          }
1871    
1872          @Override public int size() {
1873            return distinctElements();
1874          }
1875    
1876          @Override public boolean isEmpty() {
1877            return multimap().isEmpty();
1878          }
1879    
1880          @Override public boolean contains(@Nullable Object o) {
1881            if (o instanceof Multiset.Entry<?>) {
1882              Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
1883              Collection<V> collection = multimap().asMap().get(entry.getElement());
1884              return collection != null && collection.size() == entry.getCount();
1885            }
1886            return false;
1887          }
1888    
1889          @Override public boolean remove(@Nullable Object o) {
1890            if (o instanceof Multiset.Entry<?>) {
1891              Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
1892              Collection<V> collection = multimap().asMap().get(entry.getElement());
1893              if (collection != null && collection.size() == entry.getCount()) {
1894                collection.clear();
1895                return true;
1896              }
1897            }
1898            return false;
1899          }
1900        }
1901    
1902        @Override public boolean contains(@Nullable Object element) {
1903          return multimap().containsKey(element);
1904        }
1905    
1906        @Override public Iterator<K> iterator() {
1907          return Maps.keyIterator(multimap().entries().iterator());
1908        }
1909    
1910        @Override public int count(@Nullable Object element) {
1911          try {
1912            if (multimap().containsKey(element)) {
1913              Collection<V> values = multimap().asMap().get(element);
1914              return (values == null) ? 0 : values.size();
1915            }
1916            return 0;
1917          } catch (ClassCastException e) {
1918            return 0;
1919          } catch (NullPointerException e) {
1920            return 0;
1921          }
1922        }
1923    
1924        @Override public int remove(@Nullable Object element, int occurrences) {
1925          checkArgument(occurrences >= 0);
1926          if (occurrences == 0) {
1927            return count(element);
1928          }
1929    
1930          Collection<V> values;
1931          try {
1932            values = multimap().asMap().get(element);
1933          } catch (ClassCastException e) {
1934            return 0;
1935          } catch (NullPointerException e) {
1936            return 0;
1937          }
1938    
1939          if (values == null) {
1940            return 0;
1941          }
1942    
1943          int oldCount = values.size();
1944          if (occurrences >= oldCount) {
1945            values.clear();
1946          } else {
1947            Iterator<V> iterator = values.iterator();
1948            for (int i = 0; i < occurrences; i++) {
1949              iterator.next();
1950              iterator.remove();
1951            }
1952          }
1953          return oldCount;
1954        }
1955    
1956        @Override public void clear() {
1957          multimap().clear();
1958        }
1959    
1960        @Override public Set<K> elementSet() {
1961          return multimap().keySet();
1962        }
1963      }
1964    
1965      static abstract class Values<K, V> extends AbstractCollection<V> {
1966        abstract Multimap<K, V> multimap();
1967    
1968        @Override public Iterator<V> iterator() {
1969          return Maps.valueIterator(multimap().entries().iterator());
1970        }
1971    
1972        @Override public int size() {
1973          return multimap().size();
1974        }
1975    
1976        @Override public boolean contains(@Nullable Object o) {
1977          return multimap().containsValue(o);
1978        }
1979    
1980        @Override public void clear() {
1981          multimap().clear();
1982        }
1983      }
1984    
1985      /**
1986       * A skeleton implementation of {@link Multimap#entries()}.
1987       */
1988      static abstract class Entries<K, V> extends
1989          AbstractCollection<Map.Entry<K, V>> {
1990        abstract Multimap<K, V> multimap();
1991    
1992        @Override public int size() {
1993          return multimap().size();
1994        }
1995    
1996        @Override public boolean contains(@Nullable Object o) {
1997          if (o instanceof Map.Entry<?, ?>) {
1998            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1999            return multimap().containsEntry(entry.getKey(), entry.getValue());
2000          }
2001          return false;
2002        }
2003    
2004        @Override public boolean remove(@Nullable Object o) {
2005          if (o instanceof Map.Entry<?, ?>) {
2006            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
2007            return multimap().remove(entry.getKey(), entry.getValue());
2008          }
2009          return false;
2010        }
2011    
2012        @Override public void clear() {
2013          multimap().clear();
2014        }
2015      }
2016    
2017      /**
2018       * A skeleton implementation of {@link SetMultimap#entries()}.
2019       */
2020      static abstract class EntrySet<K, V> extends Entries<K, V> implements
2021          Set<Map.Entry<K, V>> {
2022        @Override public int hashCode() {
2023          return Sets.hashCodeImpl(this);
2024        }
2025    
2026        @Override public boolean equals(@Nullable Object obj) {
2027          return Sets.equalsImpl(this, obj);
2028        }
2029      }
2030    
2031      /**
2032       * A skeleton implementation of {@link Multimap#asMap()}.
2033       */
2034      static abstract class AsMap<K, V> extends
2035          Maps.ImprovedAbstractMap<K, Collection<V>> {
2036        abstract Multimap<K, V> multimap();
2037    
2038        @Override public abstract int size();
2039    
2040        abstract Iterator<Entry<K, Collection<V>>> entryIterator();
2041    
2042        @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
2043          return new EntrySet();
2044        }
2045    
2046        void removeValuesForKey(Object key){
2047          multimap().removeAll(key);
2048        }
2049    
2050        class EntrySet extends Maps.EntrySet<K, Collection<V>> {
2051          @Override Map<K, Collection<V>> map() {
2052            return AsMap.this;
2053          }
2054    
2055          @Override public Iterator<Entry<K, Collection<V>>> iterator() {
2056            return entryIterator();
2057          }
2058    
2059          @Override public boolean remove(Object o) {
2060            if (!contains(o)) {
2061              return false;
2062            }
2063            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
2064            removeValuesForKey(entry.getKey());
2065            return true;
2066          }
2067        }
2068    
2069        @SuppressWarnings("unchecked")
2070        @Override public Collection<V> get(Object key) {
2071          return containsKey(key) ? multimap().get((K) key) : null;
2072        }
2073    
2074        @Override public Collection<V> remove(Object key) {
2075          return containsKey(key) ? multimap().removeAll(key) : null;
2076        }
2077    
2078        @Override public Set<K> keySet() {
2079          return multimap().keySet();
2080        }
2081    
2082        @Override public boolean isEmpty() {
2083          return multimap().isEmpty();
2084        }
2085    
2086        @Override public boolean containsKey(Object key) {
2087          return multimap().containsKey(key);
2088        }
2089    
2090        @Override public void clear() {
2091          multimap().clear();
2092        }
2093      }
2094    
2095      /**
2096       * Returns a multimap containing the mappings in {@code unfiltered} whose keys
2097       * satisfy a predicate. The returned multimap is a live view of
2098       * {@code unfiltered}; changes to one affect the other.
2099       *
2100       * <p>The resulting multimap's views have iterators that don't support
2101       * {@code remove()}, but all other methods are supported by the multimap and
2102       * its views. When adding a key that doesn't satisfy the predicate, the
2103       * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
2104       * methods throw an {@link IllegalArgumentException}.
2105       *
2106       * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
2107       * the filtered multimap or its views, only mappings whose keys satisfy the
2108       * filter will be removed from the underlying multimap.
2109       *
2110       * <p>The returned multimap isn't threadsafe or serializable, even if
2111       * {@code unfiltered} is.
2112       *
2113       * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
2114       * across every key/value mapping in the underlying multimap and determine
2115       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
2116       * faster to copy the filtered multimap and use the copy.
2117       *
2118       * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
2119       * as documented at {@link Predicate#apply}. Do not provide a predicate such
2120       * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
2121       * with equals.
2122       *
2123       * @since 11.0
2124       */
2125      @Beta
2126      @GwtIncompatible(value = "untested")
2127      public static <K, V> Multimap<K, V> filterKeys(
2128        Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2129        checkNotNull(keyPredicate);
2130        Predicate<Entry<K, V>> entryPredicate =
2131            new Predicate<Entry<K, V>>() {
2132              @Override
2133              public boolean apply(Entry<K, V> input) {
2134                return keyPredicate.apply(input.getKey());
2135              }
2136            };
2137        return filterEntries(unfiltered, entryPredicate);
2138      }
2139    
2140      /**
2141       * Returns a multimap containing the mappings in {@code unfiltered} whose values
2142       * satisfy a predicate. The returned multimap is a live view of
2143       * {@code unfiltered}; changes to one affect the other.
2144       *
2145       * <p>The resulting multimap's views have iterators that don't support
2146       * {@code remove()}, but all other methods are supported by the multimap and
2147       * its views. When adding a value that doesn't satisfy the predicate, the
2148       * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
2149       * methods throw an {@link IllegalArgumentException}.
2150       *
2151       * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
2152       * the filtered multimap or its views, only mappings whose value satisfy the
2153       * filter will be removed from the underlying multimap.
2154       *
2155       * <p>The returned multimap isn't threadsafe or serializable, even if
2156       * {@code unfiltered} is.
2157       *
2158       * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
2159       * across every key/value mapping in the underlying multimap and determine
2160       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
2161       * faster to copy the filtered multimap and use the copy.
2162       *
2163       * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
2164       * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
2165       * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
2166       * inconsistent with equals.
2167       *
2168       * @since 11.0
2169       */
2170      @Beta
2171      @GwtIncompatible(value = "untested")
2172      public static <K, V> Multimap<K, V> filterValues(
2173        Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2174        checkNotNull(valuePredicate);
2175        Predicate<Entry<K, V>> entryPredicate =
2176            new Predicate<Entry<K, V>>() {
2177              @Override
2178              public boolean apply(Entry<K, V> input) {
2179                return valuePredicate.apply(input.getValue());
2180              }
2181            };
2182        return filterEntries(unfiltered, entryPredicate);
2183      }
2184    
2185      /**
2186       * Returns a multimap containing the mappings in {@code unfiltered} that
2187       * satisfy a predicate. The returned multimap is a live view of
2188       * {@code unfiltered}; changes to one affect the other.
2189       *
2190       * <p>The resulting multimap's views have iterators that don't support
2191       * {@code remove()}, but all other methods are supported by the multimap and
2192       * its views. When adding a key/value pair that doesn't satisfy the predicate,
2193       * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
2194       * methods throw an {@link IllegalArgumentException}.
2195       *
2196       * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
2197       * the filtered multimap or its views, only mappings whose keys satisfy the
2198       * filter will be removed from the underlying multimap.
2199       *
2200       * <p>The returned multimap isn't threadsafe or serializable, even if
2201       * {@code unfiltered} is.
2202       *
2203       * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
2204       * across every key/value mapping in the underlying multimap and determine
2205       * which satisfy the filter. When a live view is <i>not</i> needed, it may be
2206       * faster to copy the filtered multimap and use the copy.
2207       *
2208       * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
2209       * equals</i>, as documented at {@link Predicate#apply}.
2210       *
2211       * @since 11.0
2212       */
2213      @Beta
2214      @GwtIncompatible(value = "untested")
2215      public static <K, V> Multimap<K, V> filterEntries(
2216        Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2217        checkNotNull(entryPredicate);
2218        return (unfiltered instanceof FilteredMultimap)
2219            ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate)
2220            : new FilteredMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
2221      }
2222    
2223      /**
2224       * Support removal operations when filtering a filtered multimap. Since a
2225       * filtered multimap has iterators that don't support remove, passing one to
2226       * the FilteredMultimap constructor would lead to a multimap whose removal
2227       * operations would fail. This method combines the predicates to avoid that
2228       * problem.
2229       */
2230      private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> map,
2231          Predicate<? super Entry<K, V>> entryPredicate) {
2232        Predicate<Entry<K, V>> predicate
2233            = Predicates.and(map.predicate, entryPredicate);
2234        return new FilteredMultimap<K, V>(map.unfiltered, predicate);
2235      }
2236    
2237      private static class FilteredMultimap<K, V> implements Multimap<K, V> {
2238        final Multimap<K, V> unfiltered;
2239        final Predicate<? super Entry<K, V>> predicate;
2240    
2241        FilteredMultimap(Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
2242          this.unfiltered = unfiltered;
2243          this.predicate = predicate;
2244        }
2245    
2246        @Override public int size() {
2247          return entries().size();
2248        }
2249    
2250        @Override public boolean isEmpty() {
2251          return entries().isEmpty();
2252        }
2253    
2254        @Override public boolean containsKey(Object key) {
2255          return asMap().containsKey(key);
2256        }
2257    
2258        @Override public boolean containsValue(Object value) {
2259          return values().contains(value);
2260        }
2261    
2262        // This method should be called only when key is a K and value is a V.
2263        @SuppressWarnings("unchecked")
2264        boolean satisfiesPredicate(Object key, Object value) {
2265          return predicate.apply(Maps.immutableEntry((K) key, (V) value));
2266        }
2267    
2268        @Override public boolean containsEntry(Object key, Object value) {
2269          return unfiltered.containsEntry(key, value) && satisfiesPredicate(key, value);
2270        }
2271    
2272        @Override public boolean put(K key, V value) {
2273          checkArgument(satisfiesPredicate(key, value));
2274          return unfiltered.put(key, value);
2275        }
2276    
2277        @Override public boolean remove(Object key, Object value) {
2278          return containsEntry(key, value) ? unfiltered.remove(key, value) : false;
2279        }
2280    
2281        @Override public boolean putAll(K key, Iterable<? extends V> values) {
2282          for (V value : values) {
2283            checkArgument(satisfiesPredicate(key, value));
2284          }
2285          return unfiltered.putAll(key, values);
2286        }
2287    
2288        @Override public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
2289          for (Entry<? extends K, ? extends V> entry : multimap.entries()) {
2290            checkArgument(satisfiesPredicate(entry.getKey(), entry.getValue()));
2291          }
2292          return unfiltered.putAll(multimap);
2293        }
2294    
2295        @Override public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
2296          for (V value : values) {
2297            checkArgument(satisfiesPredicate(key, value));
2298          }
2299          // Not calling unfiltered.replaceValues() since values that don't satisify
2300          // the filter should remain in the multimap.
2301          Collection<V> oldValues = removeAll(key);
2302          unfiltered.putAll(key, values);
2303          return oldValues;
2304        }
2305    
2306        @Override public Collection<V> removeAll(Object key) {
2307          List<V> removed = Lists.newArrayList();
2308          Collection<V> values = unfiltered.asMap().get(key);
2309          if (values != null) {
2310            Iterator<V> iterator = values.iterator();
2311            while (iterator.hasNext()) {
2312              V value = iterator.next();
2313              if (satisfiesPredicate(key, value)) {
2314                removed.add(value);
2315                iterator.remove();
2316              }
2317            }
2318          }
2319          if (unfiltered instanceof SetMultimap) {
2320            return Collections.unmodifiableSet(Sets.newLinkedHashSet(removed));
2321          } else {
2322            return Collections.unmodifiableList(removed);
2323          }
2324        }
2325    
2326        @Override public void clear() {
2327          entries().clear();
2328        }
2329    
2330        @Override public boolean equals(@Nullable Object object) {
2331          if (object == this) {
2332            return true;
2333          }
2334          if (object instanceof Multimap) {
2335            Multimap<?, ?> that = (Multimap<?, ?>) object;
2336            return asMap().equals(that.asMap());
2337          }
2338          return false;
2339        }
2340    
2341        @Override public int hashCode() {
2342          return asMap().hashCode();
2343        }
2344    
2345        @Override public String toString() {
2346          return asMap().toString();
2347        }
2348    
2349        class ValuePredicate implements Predicate<V> {
2350          final K key;
2351          ValuePredicate(K key) {
2352            this.key = key;
2353          }
2354          @Override public boolean apply(V value) {
2355            return satisfiesPredicate(key, value);
2356          }
2357        }
2358    
2359        Collection<V> filterCollection(Collection<V> collection, Predicate<V> predicate) {
2360          if (collection instanceof Set) {
2361            return Sets.filter((Set<V>) collection, predicate);
2362          } else {
2363            return Collections2.filter(collection, predicate);
2364          }
2365        }
2366    
2367        @Override public Collection<V> get(K key) {
2368          return filterCollection(unfiltered.get(key), new ValuePredicate(key));
2369        }
2370    
2371        @Override public Set<K> keySet() {
2372          return asMap().keySet();
2373        }
2374    
2375        Collection<V> values;
2376    
2377        @Override public Collection<V> values() {
2378          return (values == null) ? values = new Values() : values;
2379        }
2380    
2381        class Values extends Multimaps.Values<K, V> {
2382          @Override Multimap<K, V> multimap() {
2383            return FilteredMultimap.this;
2384          }
2385    
2386          @Override public boolean contains(@Nullable Object o) {
2387            return Iterators.contains(iterator(), o);
2388          }
2389    
2390          // Override remove methods since iterator doesn't support remove.
2391    
2392          @Override public boolean remove(Object o) {
2393            Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
2394            while (iterator.hasNext()) {
2395              Entry<K, V> entry = iterator.next();
2396              if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) {
2397                iterator.remove();
2398                return true;
2399              }
2400            }
2401            return false;
2402          }
2403    
2404          @Override public boolean removeAll(Collection<?> c) {
2405            boolean changed = false;
2406            Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
2407            while (iterator.hasNext()) {
2408              Entry<K, V> entry = iterator.next();
2409              if (c.contains(entry.getValue()) && predicate.apply(entry)) {
2410                iterator.remove();
2411                changed = true;
2412              }
2413            }
2414            return changed;
2415          }
2416    
2417          @Override public boolean retainAll(Collection<?> c) {
2418            boolean changed = false;
2419            Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
2420            while (iterator.hasNext()) {
2421              Entry<K, V> entry = iterator.next();
2422              if (!c.contains(entry.getValue()) && predicate.apply(entry)) {
2423                iterator.remove();
2424                changed = true;
2425              }
2426            }
2427            return changed;
2428          }
2429        }
2430    
2431        Collection<Entry<K, V>> entries;
2432    
2433        @Override public Collection<Entry<K, V>> entries() {
2434          return (entries == null)
2435              ? entries = Collections2.filter(unfiltered.entries(), predicate)
2436              : entries;
2437        }
2438    
2439        /**
2440         * Remove all filtered asMap() entries that satisfy the predicate.
2441         */
2442        boolean removeEntriesIf(Predicate<Map.Entry<K, Collection<V>>> removalPredicate) {
2443          Iterator<Map.Entry<K, Collection<V>>> iterator = unfiltered.asMap().entrySet().iterator();
2444          boolean changed = false;
2445          while (iterator.hasNext()) {
2446            // Determine whether to remove the filtered values with this key.
2447            Map.Entry<K, Collection<V>> entry = iterator.next();
2448            K key = entry.getKey();
2449            Collection<V> collection = entry.getValue();
2450            Predicate<V> valuePredicate = new ValuePredicate(key);
2451            Collection<V> filteredCollection = filterCollection(collection, valuePredicate);
2452            Map.Entry<K, Collection<V>> filteredEntry = Maps.immutableEntry(key, filteredCollection);
2453            if (removalPredicate.apply(filteredEntry) && !filteredCollection.isEmpty()) {
2454              changed = true;
2455              if (Iterables.all(collection, valuePredicate)) {
2456                iterator.remove();  // Remove all values for the key.
2457              } else {
2458                filteredCollection.clear();  // Remove the filtered values only.
2459              }
2460            }
2461          }
2462          return changed;
2463        }
2464    
2465        Map<K, Collection<V>> asMap;
2466    
2467        @Override public Map<K, Collection<V>> asMap() {
2468          return (asMap == null) ? asMap = createAsMap() : asMap;
2469        }
2470    
2471        static final Predicate<Collection<?>> NOT_EMPTY = new Predicate<Collection<?>>() {
2472          @Override public boolean apply(Collection<?> input) {
2473            return !input.isEmpty();
2474          }
2475        };
2476    
2477        Map<K, Collection<V>> createAsMap() {
2478          // Select the values that satisify the predicate.
2479          EntryTransformer<K, Collection<V>, Collection<V>> transformer
2480              = new EntryTransformer<K, Collection<V>, Collection<V>>() {
2481                @Override public Collection<V> transformEntry(K key, Collection<V> collection) {
2482                  return filterCollection(collection, new ValuePredicate(key));
2483                }
2484          };
2485          Map<K, Collection<V>> transformed
2486              = Maps.transformEntries(unfiltered.asMap(), transformer);
2487    
2488          // Select the keys that have at least one value remaining.
2489          Map<K, Collection<V>> filtered = Maps.filterValues(transformed, NOT_EMPTY);
2490    
2491          // Override the removal methods, since removing a map entry should not
2492          // affect values that don't satisfy the filter.
2493          return new AsMap(filtered);
2494        }
2495    
2496        class AsMap extends ForwardingMap<K, Collection<V>> {
2497         final Map<K, Collection<V>> delegate;
2498    
2499          AsMap(Map<K, Collection<V>> delegate) {
2500            this.delegate = delegate;
2501          }
2502    
2503          @Override protected Map<K, Collection<V>> delegate() {
2504            return delegate;
2505          }
2506    
2507          @Override public Collection<V> remove(Object o) {
2508            Collection<V> output = FilteredMultimap.this.removeAll(o);
2509            return output.isEmpty() ? null : output;
2510          }
2511    
2512          @Override public void clear() {
2513            FilteredMultimap.this.clear();
2514          }
2515    
2516          Set<K> keySet;
2517    
2518          @Override public Set<K> keySet() {
2519            return (keySet == null) ? keySet = new KeySet() : keySet;
2520          }
2521    
2522          class KeySet extends Maps.KeySet<K, Collection<V>> {
2523            @Override Map<K, Collection<V>> map() {
2524              return AsMap.this;
2525            }
2526    
2527            @Override public boolean remove(Object o) {
2528               Collection<V> collection = delegate.get(o);
2529               if (collection == null) {
2530                 return false;
2531               }
2532               collection.clear();
2533               return true;
2534            }
2535    
2536            @Override public boolean removeAll(Collection<?> c) {
2537              return Sets.removeAllImpl(this, c.iterator());
2538            }
2539    
2540            @Override public boolean retainAll(final Collection<?> c) {
2541              Predicate<Map.Entry<K, Collection<V>>> removalPredicate
2542                  = new Predicate<Map.Entry<K, Collection<V>>>() {
2543                    @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
2544                      return !c.contains(entry.getKey());
2545                    }
2546                  };
2547              return removeEntriesIf(removalPredicate);
2548            }
2549          }
2550    
2551          Values asMapValues;
2552    
2553          @Override public Collection<Collection<V>> values() {
2554            return (asMapValues == null) ? asMapValues = new Values() : asMapValues;
2555          }
2556    
2557          class Values extends Maps.Values<K, Collection<V>> {
2558            @Override Map<K, Collection<V>> map() {
2559              return AsMap.this;
2560            }
2561    
2562            @Override public boolean remove(Object o) {
2563              for (Collection<V> collection : this) {
2564                if (collection.equals(o)) {
2565                  collection.clear();
2566                  return true;
2567                }
2568              }
2569              return false;
2570            }
2571    
2572            @Override public boolean removeAll(final Collection<?> c) {
2573              Predicate<Map.Entry<K, Collection<V>>> removalPredicate
2574                  = new Predicate<Map.Entry<K, Collection<V>>>() {
2575                    @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
2576                      return c.contains(entry.getValue());
2577                    }
2578                  };
2579              return removeEntriesIf(removalPredicate);
2580            }
2581    
2582            @Override public boolean retainAll(final Collection<?> c) {
2583              Predicate<Map.Entry<K, Collection<V>>> removalPredicate
2584                  = new Predicate<Map.Entry<K, Collection<V>>>() {
2585                    @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
2586                      return !c.contains(entry.getValue());
2587                    }
2588                  };
2589              return removeEntriesIf(removalPredicate);
2590            }
2591          }
2592    
2593          EntrySet entrySet;
2594    
2595          @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
2596            return (entrySet == null) ? entrySet = new EntrySet(super.entrySet()) : entrySet;
2597          }
2598    
2599          class EntrySet extends Maps.EntrySet<K, Collection<V>> {
2600            Set<Map.Entry<K, Collection<V>>> delegateEntries;
2601    
2602            public EntrySet(Set<Map.Entry<K, Collection<V>>> delegateEntries) {
2603              this.delegateEntries = delegateEntries;
2604            }
2605    
2606            @Override Map<K, Collection<V>> map() {
2607              return AsMap.this;
2608            }
2609    
2610            @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
2611              return delegateEntries.iterator();
2612            }
2613    
2614            @Override public boolean remove(Object o) {
2615              if (o instanceof Entry<?, ?>) {
2616                Entry<?, ?> entry = (Entry<?, ?>) o;
2617                Collection<V> collection = delegate.get(entry.getKey());
2618                if (collection != null && collection.equals(entry.getValue())) {
2619                  collection.clear();
2620                  return true;
2621                }
2622              }
2623              return false;
2624            }
2625    
2626            @Override public boolean removeAll(Collection<?> c) {
2627              return Sets.removeAllImpl(this, c);
2628            }
2629    
2630            @Override public boolean retainAll(final Collection<?> c) {
2631              Predicate<Map.Entry<K, Collection<V>>> removalPredicate
2632                  = new Predicate<Map.Entry<K, Collection<V>>>() {
2633                    @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
2634                      return !c.contains(entry);
2635                    }
2636                  };
2637              return removeEntriesIf(removalPredicate);
2638            }
2639          }
2640        }
2641    
2642        AbstractMultiset<K> keys;
2643    
2644        @Override public Multiset<K> keys() {
2645          return (keys == null) ? keys = new Keys() : keys;
2646        }
2647    
2648        class Keys extends Multimaps.Keys<K, V> {
2649          @Override Multimap<K, V> multimap() {
2650            return FilteredMultimap.this;
2651          }
2652    
2653          @Override public int remove(Object o, int occurrences) {
2654            checkArgument(occurrences >= 0);
2655            Collection<V> values = unfiltered.asMap().get(o);
2656            if (values == null) {
2657              return 0;
2658            }
2659            int priorCount = 0;
2660            int removed = 0;
2661            Iterator<V> iterator = values.iterator();
2662            while (iterator.hasNext()) {
2663              if (satisfiesPredicate(o, iterator.next())) {
2664                priorCount++;
2665                if (removed < occurrences) {
2666                  iterator.remove();
2667                  removed++;
2668                }
2669              }
2670            }
2671            return priorCount;
2672          }
2673    
2674          @Override Set<Multiset.Entry<K>> createEntrySet() {
2675            return new EntrySet();
2676          }
2677    
2678          class EntrySet extends Multimaps.Keys<K, V>.KeysEntrySet {
2679            @Override
2680            public boolean removeAll(final Collection<?> c) {
2681              return Sets.removeAllImpl(this, c.iterator());
2682            }
2683    
2684            @Override public boolean retainAll(final Collection<?> c) {
2685              Predicate<Map.Entry<K, Collection<V>>> removalPredicate
2686                  = new Predicate<Map.Entry<K, Collection<V>>>() {
2687                    @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
2688                      Multiset.Entry<K> multisetEntry
2689                          = Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
2690                      return !c.contains(multisetEntry);
2691                    }
2692                  };
2693              return removeEntriesIf(removalPredicate);
2694            }
2695          }
2696        }
2697      }
2698    
2699      // TODO(jlevy): Create methods that filter a SetMultimap or SortedSetMultimap.
2700    }