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