11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkState;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Joiner;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Joiner.MapJoiner;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Objects;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Supplier;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Collections2.TransformedCollection;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.EntryTransformer;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectInputStream;
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectOutputStream;
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable;
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractCollection;
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractSet;
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.HashSet;
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NoSuchElementException;
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet;
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Provides static methods acting on or generating a {@code Multimap}.
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Robert Konigsberg
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Multimaps {
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private Multimaps() {}
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a new {@code Multimap} that uses the provided map and factory. It
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * can generate a multimap based on arbitrary {@link Map} and
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Collection} classes.
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The {@code factory}-generated and {@code map} classes determine the
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap iteration order. They also specify the behavior of the
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code equals}, {@code hashCode}, and {@code toString} methods for the
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap and its returned views. However, the multimap's {@code get}
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * method returns instances of a different class than {@code factory.get()}
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * does.
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is serializable if {@code map}, {@code factory}, the
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * collections generated by {@code factory}, and the multimap contents are all
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is not threadsafe when any concurrent operations update the
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap, even if {@code map} and the instances generated by
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code factory} are. Concurrent read operations will work correctly. To
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * allow concurrent update operations, wrap the multimap with a call to
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #synchronizedMultimap}.
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Call this method only when the simpler methods
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()},
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()},
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link TreeMultimap#create()}, and
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note: the multimap assumes complete ownership over of {@code map} and
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the collections returned by {@code factory}. Those objects should not be
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * manually updated and they should not use soft, weak, or phantom references.
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param map place to store the mapping from each key to its corresponding
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     values
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param factory supplier of new, empty collections that will each hold all
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     values for a given key
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalArgumentException if {@code map} is not empty
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map,
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Supplier<? extends Collection<V>> factory) {
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new CustomMultimap<K, V>(map, factory);
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class CustomMultimap<K, V> extends AbstractMultimap<K, V> {
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Supplier<? extends Collection<V>> factory;
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CustomMultimap(Map<K, Collection<V>> map,
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Supplier<? extends Collection<V>> factory) {
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(map);
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.factory = checkNotNull(factory);
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Collection<V> createCollection() {
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return factory.get();
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // can't use Serialization writeMultimap and populateMultimap methods since
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // there's no way to generate the empty backing map.
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** @serialData the factory and the backing map */
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectOutputStream")
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void writeObject(ObjectOutputStream stream) throws IOException {
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultWriteObject();
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(factory);
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(backingMap());
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectInputStream")
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked") // reading data stored by writeObject
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void readObject(ObjectInputStream stream)
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throws IOException, ClassNotFoundException {
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultReadObject();
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      factory = (Supplier<? extends Collection<V>>) stream.readObject();
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      setMap(map);
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java serialization not supported")
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a new {@code ListMultimap} that uses the provided map and factory.
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * It can generate a multimap based on arbitrary {@link Map} and {@link List}
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * classes.
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The {@code factory}-generated and {@code map} classes determine the
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap iteration order. They also specify the behavior of the
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code equals}, {@code hashCode}, and {@code toString} methods for the
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap and its returned views. The multimap's {@code get}, {@code
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * removeAll}, and {@code replaceValues} methods return {@code RandomAccess}
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * lists if the factory does. However, the multimap's {@code get} method
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * returns instances of a different class than does {@code factory.get()}.
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is serializable if {@code map}, {@code factory}, the
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * lists generated by {@code factory}, and the multimap contents are all
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is not threadsafe when any concurrent operations update the
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap, even if {@code map} and the instances generated by
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code factory} are. Concurrent read operations will work correctly. To
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * allow concurrent update operations, wrap the multimap with a call to
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #synchronizedListMultimap}.
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Call this method only when the simpler methods
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()}
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * won't suffice.
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note: the multimap assumes complete ownership over of {@code map} and
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the lists returned by {@code factory}. Those objects should not be manually
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * updated, they should be empty when provided, and they should not use soft,
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * weak, or phantom references.
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param map place to store the mapping from each key to its corresponding
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     values
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param factory supplier of new, empty lists that will each hold all values
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     for a given key
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalArgumentException if {@code map} is not empty
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> ListMultimap<K, V> newListMultimap(
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) {
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new CustomListMultimap<K, V>(map, factory);
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class CustomListMultimap<K, V>
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends AbstractListMultimap<K, V> {
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Supplier<? extends List<V>> factory;
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CustomListMultimap(Map<K, Collection<V>> map,
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Supplier<? extends List<V>> factory) {
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(map);
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.factory = checkNotNull(factory);
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected List<V> createCollection() {
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return factory.get();
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** @serialData the factory and the backing map */
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectOutputStream")
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void writeObject(ObjectOutputStream stream) throws IOException {
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultWriteObject();
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(factory);
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(backingMap());
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectInputStream")
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked") // reading data stored by writeObject
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void readObject(ObjectInputStream stream)
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throws IOException, ClassNotFoundException {
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultReadObject();
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      factory = (Supplier<? extends List<V>>) stream.readObject();
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      setMap(map);
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java serialization not supported")
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a new {@code SetMultimap} that uses the provided map and factory.
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * It can generate a multimap based on arbitrary {@link Map} and {@link Set}
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * classes.
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The {@code factory}-generated and {@code map} classes determine the
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap iteration order. They also specify the behavior of the
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code equals}, {@code hashCode}, and {@code toString} methods for the
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap and its returned views. However, the multimap's {@code get}
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * method returns instances of a different class than {@code factory.get()}
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * does.
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is serializable if {@code map}, {@code factory}, the
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * sets generated by {@code factory}, and the multimap contents are all
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is not threadsafe when any concurrent operations update the
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap, even if {@code map} and the instances generated by
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code factory} are. Concurrent read operations will work correctly. To
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * allow concurrent update operations, wrap the multimap with a call to
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #synchronizedSetMultimap}.
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Call this method only when the simpler methods
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()},
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link TreeMultimap#create()}, and
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note: the multimap assumes complete ownership over of {@code map} and
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the sets returned by {@code factory}. Those objects should not be manually
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * updated and they should not use soft, weak, or phantom references.
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param map place to store the mapping from each key to its corresponding
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     values
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param factory supplier of new, empty sets that will each hold all values
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     for a given key
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalArgumentException if {@code map} is not empty
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> SetMultimap<K, V> newSetMultimap(
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) {
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new CustomSetMultimap<K, V>(map, factory);
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class CustomSetMultimap<K, V>
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends AbstractSetMultimap<K, V> {
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Supplier<? extends Set<V>> factory;
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CustomSetMultimap(Map<K, Collection<V>> map,
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Supplier<? extends Set<V>> factory) {
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(map);
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.factory = checkNotNull(factory);
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Set<V> createCollection() {
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return factory.get();
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** @serialData the factory and the backing map */
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectOutputStream")
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void writeObject(ObjectOutputStream stream) throws IOException {
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultWriteObject();
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(factory);
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(backingMap());
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectInputStream")
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked") // reading data stored by writeObject
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void readObject(ObjectInputStream stream)
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throws IOException, ClassNotFoundException {
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultReadObject();
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      factory = (Supplier<? extends Set<V>>) stream.readObject();
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      setMap(map);
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("not needed in emulated source")
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a new {@code SortedSetMultimap} that uses the provided map and
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * factory. It can generate a multimap based on arbitrary {@link Map} and
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link SortedSet} classes.
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The {@code factory}-generated and {@code map} classes determine the
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap iteration order. They also specify the behavior of the
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code equals}, {@code hashCode}, and {@code toString} methods for the
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap and its returned views. However, the multimap's {@code get}
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * method returns instances of a different class than {@code factory.get()}
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * does.
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is serializable if {@code map}, {@code factory}, the
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * sets generated by {@code factory}, and the multimap contents are all
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap is not threadsafe when any concurrent operations update the
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap, even if {@code map} and the instances generated by
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code factory} are. Concurrent read operations will work correctly. To
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * allow concurrent update operations, wrap the multimap with a call to
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #synchronizedSortedSetMultimap}.
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Call this method only when the simpler methods
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link TreeMultimap#create()} and
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note: the multimap assumes complete ownership over of {@code map} and
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the sets returned by {@code factory}. Those objects should not be manually
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * updated and they should not use soft, weak, or phantom references.
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param map place to store the mapping from each key to its corresponding
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     values
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param factory supplier of new, empty sorted sets that will each hold
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     all values for a given key
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalArgumentException if {@code map} is not empty
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap(
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> map,
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Supplier<? extends SortedSet<V>> factory) {
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new CustomSortedSetMultimap<K, V>(map, factory);
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class CustomSortedSetMultimap<K, V>
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends AbstractSortedSetMultimap<K, V> {
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Supplier<? extends SortedSet<V>> factory;
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Comparator<? super V> valueComparator;
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CustomSortedSetMultimap(Map<K, Collection<V>> map,
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Supplier<? extends SortedSet<V>> factory) {
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(map);
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.factory = checkNotNull(factory);
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      valueComparator = factory.get().comparator();
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected SortedSet<V> createCollection() {
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return factory.get();
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Comparator<? super V> valueComparator() {
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return valueComparator;
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** @serialData the factory and the backing map */
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectOutputStream")
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void writeObject(ObjectOutputStream stream) throws IOException {
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultWriteObject();
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(factory);
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.writeObject(backingMap());
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectInputStream")
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked") // reading data stored by writeObject
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private void readObject(ObjectInputStream stream)
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throws IOException, ClassNotFoundException {
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      stream.defaultReadObject();
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      factory = (Supplier<? extends SortedSet<V>>) stream.readObject();
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      valueComparator = factory.get().comparator();
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> map = (Map<K, Collection<V>>) stream.readObject();
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      setMap(map);
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("not needed in emulated source")
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Copies each key-value mapping in {@code source} into {@code dest}, with
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * its key and value reversed.
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>If {@code source} is an {@link ImmutableMultimap}, consider using
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link ImmutableMultimap#inverse} instead.
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param source any multimap
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param dest the multimap to copy into; usually empty
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return {@code dest}
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V, M extends Multimap<K, V>> M invertFrom(
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<? extends V, ? extends K> source, M dest) {
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(dest);
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Map.Entry<? extends V, ? extends K> entry : source.entries()) {
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      dest.put(entry.getValue(), entry.getKey());
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return dest;
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a synchronized (thread-safe) multimap backed by the specified
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap. In order to guarantee serial access, it is critical that
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <b>all</b> access to the backing multimap is accomplished through the
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * returned multimap.
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>It is imperative that the user manually synchronize on the returned
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap when accessing any of its collection views: <pre>   {@code
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Multimap<K, V> m = Multimaps.synchronizedMultimap(
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       HashMultimap.<K, V>create());
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   ...
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Set<K> s = m.keySet();  // Needn't be in synchronized block
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   ...
4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   synchronized (m) {  // Synchronizing on m, not s!
4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     Iterator<K> i = s.iterator(); // Must be in synchronized block
4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     while (i.hasNext()) {
4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       foo(i.next());
4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     }
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   }}</pre>
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Failure to follow this advice may result in non-deterministic behavior.
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note that the generated multimap's {@link Multimap#removeAll} and
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Multimap#replaceValues} methods return collections that aren't
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * synchronized.
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified multimap is
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param multimap the multimap to be wrapped in a synchronized view
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a synchronized view of the specified multimap
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> Multimap<K, V> synchronizedMultimap(
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<K, V> multimap) {
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Synchronized.multimap(multimap, null);
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified multimap. Query operations on
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the returned multimap "read through" to the specified multimap, and
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * attempts to modify the returned multimap, either directly or through the
4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap's views, result in an {@code UnsupportedOperationException}.
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note that the generated multimap's {@link Multimap#removeAll} and
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Multimap#replaceValues} methods return collections that are
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * modifiable.
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified multimap is
4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param delegate the multimap for which an unmodifiable view is to be
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     returned
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the specified multimap
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> Multimap<K, V> unmodifiableMultimap(
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<K, V> delegate) {
4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (delegate instanceof UnmodifiableMultimap ||
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        delegate instanceof ImmutableMultimap) {
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new UnmodifiableMultimap<K, V>(delegate);
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Simply returns its argument.
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @deprecated no need to use this
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Deprecated public static <K, V> Multimap<K, V> unmodifiableMultimap(
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableMultimap<K, V> delegate) {
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return checkNotNull(delegate);
4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class UnmodifiableMultimap<K, V>
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends ForwardingMultimap<K, V> implements Serializable {
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Multimap<K, V> delegate;
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Collection<Entry<K, V>> entries;
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Multiset<K> keys;
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Set<K> keySet;
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Collection<V> values;
4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Map<K, Collection<V>> map;
4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableMultimap(final Multimap<K, V> delegate) {
4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Multimap<K, V> delegate() {
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<K, Collection<V>> asMap() {
5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> result = map;
5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        final Map<K, Collection<V>> unmodifiableMap
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            = Collections.unmodifiableMap(delegate.asMap());
5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        map = result = new ForwardingMap<K, Collection<V>>() {
5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override protected Map<K, Collection<V>> delegate() {
5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return unmodifiableMap;
5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Set<Entry<K, Collection<V>>> entrySet;
5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Set<Entry<K, Collection<V>>> result = entrySet;
5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return (result == null)
5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                ? entrySet
5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                    = unmodifiableAsMapEntries(unmodifiableMap.entrySet())
5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                : result;
5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public Collection<V> get(Object key) {
5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Collection<V> collection = unmodifiableMap.get(key);
5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return (collection == null)
5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                ? null : unmodifiableValueCollection(collection);
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Collection<Collection<V>> asMapValues;
5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public Collection<Collection<V>> values() {
5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Collection<Collection<V>> result = asMapValues;
5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return (result == null)
5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                ? asMapValues
5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                    = new UnmodifiableAsMapValues<V>(unmodifiableMap.values())
5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                : result;
5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public boolean containsValue(Object o) {
5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return values().contains(o);
5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<Entry<K, V>> entries() {
5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<Entry<K, V>> result = entries;
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        entries = result = unmodifiableEntries(delegate.entries());
5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> get(K key) {
5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return unmodifiableValueCollection(delegate.get(key));
5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Multiset<K> keys() {
5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multiset<K> result = keys;
5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        keys = result = Multisets.unmodifiableMultiset(delegate.keys());
5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<K> keySet() {
5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<K> result = keySet;
5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        keySet = result = Collections.unmodifiableSet(delegate.keySet());
5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean put(K key, V value) {
5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean putAll(K key, Iterable<? extends V> values) {
5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean remove(Object key, Object value) {
5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> removeAll(Object key) {
5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> replaceValues(
6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        K key, Iterable<? extends V> values) {
6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> values() {
6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<V> result = values;
6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        values = result = Collections.unmodifiableCollection(delegate.values());
6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class UnmodifiableAsMapValues<V>
6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends ForwardingCollection<Collection<V>> {
6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Collection<Collection<V>> delegate;
6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableAsMapValues(Collection<Collection<V>> delegate) {
6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = Collections.unmodifiableCollection(delegate);
6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Collection<Collection<V>> delegate() {
6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Iterator<Collection<V>> iterator() {
6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Iterator<Collection<V>> iterator = delegate.iterator();
6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new Iterator<Collection<V>>() {
6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public boolean hasNext() {
6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return iterator.hasNext();
6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public Collection<V> next() {
6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return unmodifiableValueCollection(iterator.next());
6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public void remove() {
6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          throw new UnsupportedOperationException();
6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Object[] toArray() {
6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray();
6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public <T> T[] toArray(T[] array) {
6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray(array);
6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean contains(Object o) {
6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardContains(o);
6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsAll(Collection<?> c) {
6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardContainsAll(c);
6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class UnmodifiableListMultimap<K, V>
6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> {
6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableListMultimap(ListMultimap<K, V> delegate) {
6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(delegate);
6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public ListMultimap<K, V> delegate() {
6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (ListMultimap<K, V>) super.delegate();
6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<V> get(K key) {
6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableList(delegate().get(key));
6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<V> removeAll(Object key) {
6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<V> replaceValues(
6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        K key, Iterable<? extends V> values) {
6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class UnmodifiableSetMultimap<K, V>
6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> {
6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableSetMultimap(SetMultimap<K, V> delegate) {
6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(delegate);
6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SetMultimap<K, V> delegate() {
6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (SetMultimap<K, V>) super.delegate();
6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<V> get(K key) {
6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /*
6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * Note that this doesn't return a SortedSet when delegate is a
6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * SortedSetMultiset, unlike (SortedSet<V>) super.get().
6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       */
6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSet(delegate().get(key));
6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<Map.Entry<K, V>> entries() {
6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Maps.unmodifiableEntrySet(delegate().entries());
6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<V> removeAll(Object key) {
6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<V> replaceValues(
7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        K key, Iterable<? extends V> values) {
7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class UnmodifiableSortedSetMultimap<K, V>
7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> {
7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) {
7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(delegate);
7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSetMultimap<K, V> delegate() {
7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (SortedSetMultimap<K, V>) super.delegate();
7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<V> get(K key) {
7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSortedSet(delegate().get(key));
7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<V> removeAll(Object key) {
7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<V> replaceValues(
7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        K key, Iterable<? extends V> values) {
7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Comparator<? super V> valueComparator() {
7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate().valueComparator();
7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the
7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * specified multimap.
7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified multimap is
7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param multimap the multimap to be wrapped
7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a synchronized view of the specified multimap
7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> SetMultimap<K, V> synchronizedSetMultimap(
7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SetMultimap<K, V> multimap) {
7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Synchronized.setMultimap(multimap, null);
7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified {@code SetMultimap}. Query
7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * operations on the returned multimap "read through" to the specified
7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap, and attempts to modify the returned multimap, either directly or
7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * through the multimap's views, result in an
7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code UnsupportedOperationException}.
7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note that the generated multimap's {@link Multimap#removeAll} and
7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Multimap#replaceValues} methods return collections that are
7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * modifiable.
7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified multimap is
7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param delegate the multimap for which an unmodifiable view is to be
7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     returned
7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the specified multimap
7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SetMultimap<K, V> delegate) {
7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (delegate instanceof UnmodifiableSetMultimap ||
7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        delegate instanceof ImmutableSetMultimap) {
7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new UnmodifiableSetMultimap<K, V>(delegate);
7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Simply returns its argument.
7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @deprecated no need to use this
7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Deprecated public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableSetMultimap<K, V> delegate) {
7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return checkNotNull(delegate);
7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by
7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the specified multimap.
7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified multimap is
7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param multimap the multimap to be wrapped
7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a synchronized view of the specified multimap
7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> SortedSetMultimap<K, V>
7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) {
8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Synchronized.sortedSetMultimap(multimap, null);
8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified {@code SortedSetMultimap}.
8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Query operations on the returned multimap "read through" to the specified
8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap, and attempts to modify the returned multimap, either directly or
8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * through the multimap's views, result in an
8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code UnsupportedOperationException}.
8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note that the generated multimap's {@link Multimap#removeAll} and
8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Multimap#replaceValues} methods return collections that are
8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * modifiable.
8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified multimap is
8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param delegate the multimap for which an unmodifiable view is to be
8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     returned
8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the specified multimap
8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap(
8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SortedSetMultimap<K, V> delegate) {
8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (delegate instanceof UnmodifiableSortedSetMultimap) {
8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new UnmodifiableSortedSetMultimap<K, V>(delegate);
8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the
8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * specified multimap.
8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param multimap the multimap to be wrapped
8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a synchronized view of the specified multimap
8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> ListMultimap<K, V> synchronizedListMultimap(
8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ListMultimap<K, V> multimap) {
8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Synchronized.listMultimap(multimap, null);
8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified {@code ListMultimap}. Query
8451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * operations on the returned multimap "read through" to the specified
8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap, and attempts to modify the returned multimap, either directly or
8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * through the multimap's views, result in an
8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code UnsupportedOperationException}.
8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note that the generated multimap's {@link Multimap#removeAll} and
8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Multimap#replaceValues} methods return collections that are
8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * modifiable.
8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified multimap is
8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param delegate the multimap for which an unmodifiable view is to be
8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     returned
8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the specified multimap
8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ListMultimap<K, V> delegate) {
8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (delegate instanceof UnmodifiableListMultimap ||
8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        delegate instanceof ImmutableListMultimap) {
8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
8661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new UnmodifiableListMultimap<K, V>(delegate);
8681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Simply returns its argument.
8721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @deprecated no need to use this
8741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
8751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Deprecated public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
8771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableListMultimap<K, V> delegate) {
8781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return checkNotNull(delegate);
8791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified collection, preserving the
8831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and
8841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code Collection}, in that order of preference.
8851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
8861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param collection the collection for which to return an unmodifiable view
8871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the collection
8881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <V> Collection<V> unmodifiableValueCollection(
8901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<V> collection) {
8911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (collection instanceof SortedSet) {
8921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (collection instanceof Set) {
8941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSet((Set<V>) collection);
8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (collection instanceof List) {
8961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableList((List<V>) collection);
8971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Collections.unmodifiableCollection(collection);
8991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
9021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified multimap {@code asMap} entry.
9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The {@link Entry#setValue} operation throws an {@link
9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * UnsupportedOperationException}, and the collection returned by {@code
9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * getValue} is also an unmodifiable (type-preserving) view. This also has the
9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * side-effect of redefining equals to comply with the Map.Entry contract, and
9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * to avoid a possible nefarious implementation of equals.
9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param entry the entry for which to return an unmodifiable view
9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the entry
9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <K, V> Map.Entry<K, Collection<V>> unmodifiableAsMapEntry(
9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Map.Entry<K, Collection<V>> entry) {
9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(entry);
9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new AbstractMapEntry<K, Collection<V>>() {
9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public K getKey() {
9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return entry.getKey();
9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Collection<V> getValue() {
9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return unmodifiableValueCollection(entry.getValue());
9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified collection of entries. The
9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Entry#setValue} operation throws an {@link
9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * UnsupportedOperationException}. If the specified collection is a {@code
9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Set}, the returned collection is also a {@code Set}.
9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param entries the entries for which to return an unmodifiable view
9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the entries
9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <K, V> Collection<Entry<K, V>> unmodifiableEntries(
9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<Entry<K, V>> entries) {
9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (entries instanceof Set) {
9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries);
9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new Maps.UnmodifiableEntries<K, V>(
9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collections.unmodifiableCollection(entries));
9421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
9451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified set of {@code asMap} entries.
9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The {@link Entry#setValue} operation throws an {@link
9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * UnsupportedOperationException}, as do any operations that attempt to modify
9481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the returned collection.
9491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
9501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param asMapEntries the {@code asMap} entries for which to return an
9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     unmodifiable view
9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the collection entries
9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
9541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <K, V> Set<Entry<K, Collection<V>>> unmodifiableAsMapEntries(
9551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<Entry<K, Collection<V>>> asMapEntries) {
9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new UnmodifiableAsMapEntries<K, V>(
9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collections.unmodifiableSet(asMapEntries));
9581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Multimaps#unmodifiableAsMapEntries */
9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class UnmodifiableAsMapEntries<K, V>
9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends ForwardingSet<Entry<K, Collection<V>>> {
9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Set<Entry<K, Collection<V>>> delegate;
9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableAsMapEntries(Set<Entry<K, Collection<V>>> delegate) {
9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = delegate;
9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Set<Entry<K, Collection<V>>> delegate() {
9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Iterator<Entry<K, Collection<V>>> iterator() {
9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Iterator<Entry<K, Collection<V>>> iterator = delegate.iterator();
9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new ForwardingIterator<Entry<K, Collection<V>>>() {
9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override protected Iterator<Entry<K, Collection<V>>> delegate() {
9761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return iterator;
9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
9781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Entry<K, Collection<V>> next() {
9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return unmodifiableAsMapEntry(iterator.next());
9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Object[] toArray() {
9851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray();
9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public <T> T[] toArray(T[] array) {
9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray(array);
9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean contains(Object o) {
9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Maps.containsEntryImpl(delegate(), o);
9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsAll(Collection<?> c) {
9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardContainsAll(c);
9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(@Nullable Object object) {
10011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardEquals(object);
10021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a multimap view of the specified map. The multimap is backed by the
10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * map, so changes to the map are reflected in the multimap, and vice versa.
10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * If the map is modified while an iteration over one of the multimap's
10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * collection views is in progress (except through the iterator's own {@code
10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * remove} operation, or through the {@code setValue} operation on a map entry
10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * returned by the iterator), the results of the iteration are undefined.
10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The multimap supports mapping removal, which removes the corresponding
10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * mapping from the map. It does not support any operations which might add
10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}.
10161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap will be serializable if the specified map is
10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param map the backing map for the returned multimap view
10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) {
10231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new MapMultimap<K, V>(map);
10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Multimaps#forMap */
10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class MapMultimap<K, V>
10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements SetMultimap<K, V>, Serializable {
10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Map<K, V> map;
10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    transient Map<K, Collection<V>> asMap;
10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapMultimap(Map<K, V> map) {
10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.map = checkNotNull(map);
10341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public int size() {
10381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.size();
10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean isEmpty() {
10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.isEmpty();
10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
10471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean containsKey(Object key) {
10481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.containsKey(key);
10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
10521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean containsValue(Object value) {
10531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.containsValue(value);
10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean containsEntry(Object key, Object value) {
10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.entrySet().contains(Maps.immutableEntry(key, value));
10591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<V> get(final K key) {
10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new AbstractSet<V>() {
10641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Iterator<V> iterator() {
10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return new Iterator<V>() {
10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            int i;
10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override
10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            public boolean hasNext() {
10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return (i == 0) && map.containsKey(key);
10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override
10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            public V next() {
10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              if (!hasNext()) {
10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                throw new NoSuchElementException();
10771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              }
10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              i++;
10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return map.get(key);
10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override
10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            public void remove() {
10841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              checkState(i == 1);
10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              i = -1;
10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              map.remove(key);
10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          };
10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public int size() {
10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return map.containsKey(key) ? 1 : 0;
10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
10941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean put(K key, V value) {
10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean putAll(K key, Iterable<? extends V> values) {
11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
11091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
11101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<V> replaceValues(K key, Iterable<? extends V> values) {
11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean remove(Object key, Object value) {
11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.entrySet().remove(Maps.immutableEntry(key, value));
11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<V> removeAll(Object key) {
11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<V> values = new HashSet<V>(2);
11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!map.containsKey(key)) {
11261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return values;
11271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      values.add(map.remove(key));
11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return values;
11301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void clear() {
11341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.clear();
11351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<K> keySet() {
11391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.keySet();
11401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Multiset<K> keys() {
11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Multisets.forSet(map.keySet());
11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Collection<V> values() {
11491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.values();
11501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<Entry<K, V>> entries() {
11541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.entrySet();
11551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
11581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<K, Collection<V>> asMap() {
11591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> result = asMap;
11601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (result == null) {
11611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        asMap = result = new AsMap();
11621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return result;
11641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(@Nullable Object object) {
11671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (object == this) {
11681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return true;
11691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (object instanceof Multimap) {
11711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Multimap<?, ?> that = (Multimap<?, ?>) object;
11721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return this.size() == that.size() && asMap().equals(that.asMap());
11731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
11751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return map.hashCode();
11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final MapJoiner JOINER
11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Joiner.on("], ").withKeyValueSeparator("=[").useForNull("null");
11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (map.isEmpty()) {
11861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return "{}";
11871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      StringBuilder builder
11891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          = Collections2.newStringBuilderForCollection(map.size()).append('{');
11901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      JOINER.appendTo(builder, map);
11911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return builder.append("]}").toString();
11921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
11931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** @see MapMultimap#asMap */
11951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
11961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public int size() {
11971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return map.size();
11981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Iterator<Entry<K, Collection<V>>> iterator() {
12011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new Iterator<Entry<K, Collection<V>>>() {
12021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          final Iterator<K> keys = map.keySet().iterator();
12031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
12051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public boolean hasNext() {
12061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return keys.hasNext();
12071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
12081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
12091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Entry<K, Collection<V>> next() {
12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            final K key = keys.next();
12111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return new AbstractMapEntry<K, Collection<V>>() {
12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              @Override public K getKey() {
12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                return key;
12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              }
12151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              @Override public Collection<V> getValue() {
12161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                return get(key);
12171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              }
12181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            };
12191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
12211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public void remove() {
12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            keys.remove();
12231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
12241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
12251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
12261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean contains(Object o) {
12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (!(o instanceof Entry)) {
12291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Entry<?, ?> entry = (Entry<?, ?>) o;
12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (!(entry.getValue() instanceof Set)) {
12331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Set<?> set = (Set<?>) entry.getValue();
12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (set.size() == 1)
12371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            && containsEntry(entry.getKey(), set.iterator().next());
12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean remove(Object o) {
12411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (!(o instanceof Entry)) {
12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Entry<?, ?> entry = (Entry<?, ?>) o;
12451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (!(entry.getValue() instanceof Set)) {
12461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Set<?> set = (Set<?>) entry.getValue();
12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (set.size() == 1)
12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            && map.entrySet().remove(
12511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                Maps.immutableEntry(entry.getKey(), set.iterator().next()));
12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** @see MapMultimap#asMap */
12561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class AsMap extends Maps.ImprovedAbstractMap<K, Collection<V>> {
12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new AsMapEntries();
12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
12601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // The following methods are included for performance.
12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean containsKey(Object key) {
12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return map.containsKey(key);
12651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
12661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @SuppressWarnings("unchecked")
12681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Collection<V> get(Object key) {
12691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<V> collection = MapMultimap.this.get((K) key);
12701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return collection.isEmpty() ? null : collection;
12711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
12721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Collection<V> remove(Object key) {
12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<V> collection = removeAll(key);
12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return collection.isEmpty() ? null : collection;
12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 7845222491160860175L;
12791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a view of a multimap where each value is transformed by a function.
12831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * All other properties of the multimap, such as iteration order, are left
12841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * intact. For example, the code: <pre>   {@code
12851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Multimap<String, Integer> multimap =
12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6);
12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Function<Integer, String> square = new Function<Integer, String>() {
12891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     public String apply(Integer in) {
12901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       return Integer.toString(in * in);
12911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     }
12921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * };
12931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Multimap<String, String> transformed =
12941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     Multimaps.transformValues(multimap, square);
12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   System.out.println(transformed);}</pre>
12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ... prints {@code {a=[4, 16], b=[9, 9], c=[6]}}.
12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Changes in the underlying multimap are reflected in this view.
13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Conversely, this view supports removal operations, and these are reflected
13011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * in the underlying multimap.
13021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>It's acceptable for the underlying multimap to contain null keys, and
13041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * even null values provided that the function is capable of accepting null
13051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * input.  The transformed multimap might contain null values, if the function
13061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * sometimes gives a null result.
13071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap is not thread-safe or serializable, even if the
13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying multimap is.  The {@code equals} and {@code hashCode} methods
13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * of the returned multimap are meaningless, since there is not a definition
13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * of {@code equals} or {@code hashCode} for general collections, and
13121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code get()} will return a general {@code Collection} as opposed to a
13131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code List} or a {@code Set}.
13141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The function is applied lazily, invoked when needed. This is necessary
13161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * for the returned multimap to be a view, but it means that the function will
13171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * be applied many times for bulk operations like
13181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * perform well, {@code function} should be fast. To avoid lazy evaluation
13201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * when the returned multimap doesn't need to be a view, copy the returned
13211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap into a new multimap of your choosing.
13221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 7.0
13241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
13251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
13261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V1, V2> Multimap<K, V2> transformValues(
13271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
13281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(function);
13291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EntryTransformer<K, V1, V2> transformer =
13301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new EntryTransformer<K, V1, V2>() {
13311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
13321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public V2 transformEntry(K key, V1 value) {
13331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return function.apply(value);
13341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return transformEntries(fromMultimap, transformer);
13371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
13381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
13401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a view of a multimap whose values are derived from the original
13411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap's entries. In contrast to {@link #transformValues}, this method's
13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * entry-transformation logic may depend on the key as well as the value.
13431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>All other properties of the transformed multimap, such as iteration
13451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * order, are left intact. For example, the code: <pre>   {@code
13461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   SetMultimap<String, Integer> multimap =
13481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
13491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   EntryTransformer<String, Integer, String> transformer =
13501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       new EntryTransformer<String, Integer, String>() {
13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         public String transformEntry(String key, Integer value) {
13521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *            return (value >= 0) ? key : "no" + key;
13531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         }
13541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       };
13551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Multimap<String, String> transformed =
13561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       Multimaps.transformEntries(multimap, transformer);
13571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   System.out.println(transformed);}</pre>
13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ... prints {@code {a=[a, a], b=[nob]}}.
13601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Changes in the underlying multimap are reflected in this view.
13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Conversely, this view supports removal operations, and these are reflected
13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * in the underlying multimap.
13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>It's acceptable for the underlying multimap to contain null keys and
13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * null values provided that the transformer is capable of accepting null
13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * inputs. The transformed multimap might contain null values if the
13681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * transformer sometimes gives a null result.
13691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap is not thread-safe or serializable, even if the
13711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying multimap is.  The {@code equals} and {@code hashCode} methods
13721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * of the returned multimap are meaningless, since there is not a definition
13731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * of {@code equals} or {@code hashCode} for general collections, and
13741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code get()} will return a general {@code Collection} as opposed to a
13751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code List} or a {@code Set}.
13761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The transformer is applied lazily, invoked when needed. This is
13781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * necessary for the returned multimap to be a view, but it means that the
13791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * transformer will be applied many times for bulk operations like {@link
13801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Multimap#containsValue} and {@link Object#toString}. For this to perform
13811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * well, {@code transformer} should be fast. To avoid lazy evaluation when the
13821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * returned multimap doesn't need to be a view, copy the returned multimap
13831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * into a new multimap of your choosing.
13841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
13861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
13871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * that {@code k2} is also of type {@code K}. Using an {@code
13881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * EntryTransformer} key type for which this may not hold, such as {@code
13891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ArrayList}, may risk a {@code ClassCastException} when calling methods on
13901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the transformed multimap.
13911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
13921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 7.0
13931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
13941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
13951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V1, V2> Multimap<K, V2> transformEntries(
13961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<K, V1> fromMap,
13971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      EntryTransformer<? super K, ? super V1, V2> transformer) {
13981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer);
13991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
14001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class TransformedEntriesMultimap<K, V1, V2>
14021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements Multimap<K, V2> {
14031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Multimap<K, V1> fromMultimap;
14041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final EntryTransformer<? super K, ? super V1, V2> transformer;
14051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TransformedEntriesMultimap(Multimap<K, V1> fromMultimap,
14071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        final EntryTransformer<? super K, ? super V1, V2> transformer) {
14081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.fromMultimap = checkNotNull(fromMultimap);
14091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.transformer = checkNotNull(transformer);
14101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<V2> transform(final K key, Collection<V1> values) {
14131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections2.transform(values, new Function<V1, V2>() {
14141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public V2 apply(V1 value) {
14151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return transformer.transformEntry(key, value);
14161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
14171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      });
14181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient Map<K, Collection<V2>> asMap;
14211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<K, Collection<V2>> asMap() {
14231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (asMap == null) {
14241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Map<K, Collection<V2>> aM = Maps.transformEntries(fromMultimap.asMap(),
14251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
14261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              @Override public Collection<V2> transformEntry(
14281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  K key, Collection<V1> value) {
14291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                return transform(key, value);
14301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              }
14311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            });
14321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        asMap = aM;
14331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return aM;
14341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
14351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return asMap;
14361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
14391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fromMultimap.clear();
14401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
14431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsEntry(Object key, Object value) {
14441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<V2> values = get((K) key);
14451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return values.contains(value);
14461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsKey(Object key) {
14491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromMultimap.containsKey(key);
14501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsValue(Object value) {
14531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return values().contains(value);
14541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient Collection<Entry<K, V2>> entries;
14571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<Entry<K, V2>> entries() {
14591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (entries == null) {
14601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<Entry<K, V2>> es = new TransformedEntries(transformer);
14611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        entries = es;
14621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return es;
14631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
14641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return entries;
14651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
14661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private class TransformedEntries
14681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        extends TransformedCollection<Entry<K, V1>, Entry<K, V2>> {
14691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      TransformedEntries(
14711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          final EntryTransformer<? super K, ? super V1, V2> transformer) {
14721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        super(fromMultimap.entries(),
14731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            new Function<Entry<K, V1>, Entry<K, V2>>() {
14741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              @Override public Entry<K, V2> apply(final Entry<K, V1> entry) {
14751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                return new AbstractMapEntry<K, V2>() {
14761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  @Override public K getKey() {
14781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                    return entry.getKey();
14791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  }
14801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  @Override public V2 getValue() {
14821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                    return transformer.transformEntry(
14831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                        entry.getKey(), entry.getValue());
14841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  }
14851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                };
14861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              }
14871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            });
14881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
14891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean contains(Object o) {
14911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (o instanceof Entry) {
14921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Entry<?, ?> entry = (Entry<?, ?>) o;
14931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return containsEntry(entry.getKey(), entry.getValue());
14941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
14951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
14961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
14971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @SuppressWarnings("unchecked")
14991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean remove(Object o) {
15001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (o instanceof Entry) {
15011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Entry<?, ?> entry = (Entry<?, ?>) o;
15021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Collection<V2> values = get((K) entry.getKey());
15031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return values.remove(entry.getValue());
15041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
15051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
15061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
15071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V2> get(final K key) {
15111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return transform(key, fromMultimap.get(key));
15121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean isEmpty() {
15151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromMultimap.isEmpty();
15161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<K> keySet() {
15191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromMultimap.keySet();
15201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Multiset<K> keys() {
15231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromMultimap.keys();
15241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean put(K key, V2 value) {
15271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
15281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean putAll(K key, Iterable<? extends V2> values) {
15311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
15321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean putAll(
15351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Multimap<? extends K, ? extends V2> multimap) {
15361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
15371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
15401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean remove(Object key, Object value) {
15411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return get((K) key).remove(value);
15421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
15451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V2> removeAll(Object key) {
15461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return transform((K) key, fromMultimap.removeAll(key));
15471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V2> replaceValues(
15501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        K key, Iterable<? extends V2> values) {
15511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
15521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int size() {
15551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromMultimap.size();
15561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private transient Collection<V2> values;
15591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V2> values() {
15611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (values == null) {
15621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<V2> vs = Collections2.transform(
15631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            fromMultimap.entries(), new Function<Entry<K, V1>, V2>() {
15641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              @Override public V2 apply(Entry<K, V1> entry) {
15661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                return transformer.transformEntry(
15671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                    entry.getKey(), entry.getValue());
15681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              }
15691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            });
15701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        values = vs;
15711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return vs;
15721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
15731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return values;
15741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(Object obj) {
15771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (obj instanceof Multimap) {
15781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Multimap<?, ?> other = (Multimap<?, ?>) obj;
15791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return asMap().equals(other.asMap());
15801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
15811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
15821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
15851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return asMap().hashCode();
15861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
15891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return asMap().toString();
15901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
15911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
15941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a view of a {@code ListMultimap} where each value is transformed by
15951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * a function. All other properties of the multimap, such as iteration order,
15961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * are left intact. For example, the code: <pre>   {@code
15971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
15981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   ListMultimap<String, Integer> multimap
15991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *        = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9);
16001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Function<Integer, Double> sqrt =
16011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       new Function<Integer, Double>() {
16021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         public Double apply(Integer in) {
16031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *           return Math.sqrt((int) in);
16041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         }
16051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       };
16061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   ListMultimap<String, Double> transformed = Multimaps.transformValues(map,
16071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       sqrt);
16081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   System.out.println(transformed);}</pre>
16091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}.
16111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Changes in the underlying multimap are reflected in this view.
16131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Conversely, this view supports removal operations, and these are reflected
16141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * in the underlying multimap.
16151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>It's acceptable for the underlying multimap to contain null keys, and
16171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * even null values provided that the function is capable of accepting null
16181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * input.  The transformed multimap might contain null values, if the function
16191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * sometimes gives a null result.
16201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap is not thread-safe or serializable, even if the
16221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying multimap is.
16231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The function is applied lazily, invoked when needed. This is necessary
16251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * for the returned multimap to be a view, but it means that the function will
16261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * be applied many times for bulk operations like
16271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
16281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * perform well, {@code function} should be fast. To avoid lazy evaluation
16291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * when the returned multimap doesn't need to be a view, copy the returned
16301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap into a new multimap of your choosing.
16311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 7.0
16331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
16341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
16351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V1, V2> ListMultimap<K, V2> transformValues(
16361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ListMultimap<K, V1> fromMultimap,
16371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Function<? super V1, V2> function) {
16381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(function);
16391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EntryTransformer<K, V1, V2> transformer =
16401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new EntryTransformer<K, V1, V2>() {
16411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
16421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public V2 transformEntry(K key, V1 value) {
16431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return function.apply(value);
16441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return transformEntries(fromMultimap, transformer);
16471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a view of a {@code ListMultimap} whose values are derived from the
16511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * original multimap's entries. In contrast to
16521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #transformValues(ListMultimap, Function)}, this method's
16531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * entry-transformation logic may depend on the key as well as the value.
16541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>All other properties of the transformed multimap, such as iteration
16561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * order, are left intact. For example, the code: <pre>   {@code
16571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Multimap<String, Integer> multimap =
16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       ImmutableMultimap.of("a", 1, "a", 4, "b", 6);
16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   EntryTransformer<String, Integer, String> transformer =
16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       new EntryTransformer<String, Integer, String>() {
16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         public String transformEntry(String key, Integer value) {
16631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *           return key + value;
16641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         }
16651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       };
16661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Multimap<String, String> transformed =
16671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       Multimaps.transformEntries(multimap, transformer);
16681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   System.out.println(transformed);}</pre>
16691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}.
16711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Changes in the underlying multimap are reflected in this view.
16731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Conversely, this view supports removal operations, and these are reflected
16741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * in the underlying multimap.
16751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>It's acceptable for the underlying multimap to contain null keys and
16771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * null values provided that the transformer is capable of accepting null
16781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * inputs. The transformed multimap might contain null values if the
16791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * transformer sometimes gives a null result.
16801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap is not thread-safe or serializable, even if the
16821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying multimap is.
16831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The transformer is applied lazily, invoked when needed. This is
16851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * necessary for the returned multimap to be a view, but it means that the
16861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * transformer will be applied many times for bulk operations like {@link
16871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Multimap#containsValue} and {@link Object#toString}. For this to perform
16881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * well, {@code transformer} should be fast. To avoid lazy evaluation when the
16891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * returned multimap doesn't need to be a view, copy the returned multimap
16901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * into a new multimap of your choosing.
16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
16941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * that {@code k2} is also of type {@code K}. Using an {@code
16951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * EntryTransformer} key type for which this may not hold, such as {@code
16961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * ArrayList}, may risk a {@code ClassCastException} when calling methods on
16971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the transformed multimap.
16981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
16991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 7.0
17001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
17011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
17021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V1, V2> ListMultimap<K, V2> transformEntries(
17031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ListMultimap<K, V1> fromMap,
17041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      EntryTransformer<? super K, ? super V1, V2> transformer) {
17051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new TransformedEntriesListMultimap<K, V1, V2>(fromMap, transformer);
17061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final class TransformedEntriesListMultimap<K, V1, V2>
17091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends TransformedEntriesMultimap<K, V1, V2>
17101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements ListMultimap<K, V2> {
17111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TransformedEntriesListMultimap(ListMultimap<K, V1> fromMultimap,
17131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        EntryTransformer<? super K, ? super V1, V2> transformer) {
17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(fromMultimap, transformer);
17151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override List<V2> transform(final K key, Collection<V1> values) {
17181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Lists.transform((List<V1>) values, new Function<V1, V2>() {
17191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public V2 apply(V1 value) {
17201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return transformer.transformEntry(key, value);
17211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
17221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      });
17231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<V2> get(K key) {
17261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return transform(key, fromMultimap.get(key));
17271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
17301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<V2> removeAll(Object key) {
17311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return transform((K) key, fromMultimap.removeAll(key));
17321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<V2> replaceValues(
17351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        K key, Iterable<? extends V2> values) {
17361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
17371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
17411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates an index {@code ImmutableListMultimap} that contains the results of
17421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * applying a specified function to each item in an {@code Iterable} of
17431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * values. Each value will be stored as a value in the resulting multimap,
17441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * yielding a multimap with the same size as the input iterable. The key used
17451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * to store that value in the multimap will be the result of calling the
17461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * function on that value. The resulting multimap is created as an immutable
17471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * snapshot. In the returned multimap, keys appear in the order they are first
17481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * encountered, and the values corresponding to each key appear in the same
17491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * order as they are encountered.
17501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
17511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>For example, <pre>   {@code
17521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
17531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   List<String> badGuys =
17541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
17551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Function<String, Integer> stringLengthFunction = ...;
17561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Multimap<Integer, String> index =
17571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       Multimaps.index(badGuys, stringLengthFunction);
17581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   System.out.println(index);}</pre>
17591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
17601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * prints <pre>   {@code
17611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
17621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
17631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
17641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The returned multimap is serializable if its keys and values are all
17651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
17661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
17671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param values the values to use when constructing the {@code
17681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     ImmutableListMultimap}
17691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param keyFunction the function used to produce the key for each value
17701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return {@code ImmutableListMultimap} mapping the result of evaluating the
17711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     function {@code keyFunction} on each value in the input collection to
17721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     that value
17731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws NullPointerException if any of the following cases is true:
17741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <ul>
17751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>{@code values} is null
17761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>{@code keyFunction} is null
17771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>An element in {@code values} is null
17781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>{@code keyFunction} returns {@code null} for any element of {@code
17791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         values}
17801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     </ul>
17811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
17821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> ImmutableListMultimap<K, V> index(
17831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Iterable<V> values, Function<? super V, K> keyFunction) {
17841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return index(values.iterator(), keyFunction);
17851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
17881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <b>Deprecated.</b>
17891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
17901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
17911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @deprecated use {@link #index(Iterator, Function)} by casting {@code
17921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     values} to {@code Iterator<V>}, or better yet, by implementing only
17931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     {@code Iterator} and not {@code Iterable}. <b>This method is scheduled
17941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     for deletion in March 2012.</b>
17951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
17961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
17971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Deprecated
17981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V, I extends Object & Iterable<V> & Iterator<V>>
17991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableListMultimap<K, V> index(
18001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          I values, Function<? super V, K> keyFunction) {
18011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterable<V> valuesIterable = checkNotNull(values);
18021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return index(valuesIterable, keyFunction);
18031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
18041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
18061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates an index {@code ImmutableListMultimap} that contains the results of
18071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * applying a specified function to each item in an {@code Iterator} of
18081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * values. Each value will be stored as a value in the resulting multimap,
18091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * yielding a multimap with the same size as the input iterator. The key used
18101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * to store that value in the multimap will be the result of calling the
18111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * function on that value. The resulting multimap is created as an immutable
18121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * snapshot. In the returned multimap, keys appear in the order they are first
18131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * encountered, and the values corresponding to each key appear in the same
18141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * order as they are encountered.
18151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
18161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>For example, <pre>   {@code
18171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
18181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   List<String> badGuys =
18191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
18201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Function<String, Integer> stringLengthFunction = ...;
18211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   Multimap<Integer, String> index =
18221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       Multimaps.index(badGuys.iterator(), stringLengthFunction);
18231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   System.out.println(index);}</pre>
18241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
18251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * prints <pre>   {@code
18261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
18271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
18281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
18291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The returned multimap is serializable if its keys and values are all
18301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
18311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
18321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param values the values to use when constructing the {@code
18331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     ImmutableListMultimap}
18341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param keyFunction the function used to produce the key for each value
18351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return {@code ImmutableListMultimap} mapping the result of evaluating the
18361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     function {@code keyFunction} on each value in the input collection to
18371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     that value
18381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws NullPointerException if any of the following cases is true:
18391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <ul>
18401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>{@code values} is null
18411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>{@code keyFunction} is null
18421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>An element in {@code values} is null
18431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     <li>{@code keyFunction} returns {@code null} for any element of {@code
18441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *         values}
18451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     </ul>
18461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
18471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
18481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> ImmutableListMultimap<K, V> index(
18491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Iterator<V> values, Function<? super V, K> keyFunction) {
18501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(keyFunction);
18511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableListMultimap.Builder<K, V> builder
18521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = ImmutableListMultimap.builder();
18531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    while (values.hasNext()) {
18541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      V value = values.next();
18551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(value, values);
18561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      builder.put(keyFunction.apply(value), value);
18571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
18581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return builder.build();
18591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
18601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static abstract class Keys<K, V> extends AbstractMultiset<K> {
18621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    abstract Multimap<K, V> multimap();
18631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override Iterator<Multiset.Entry<K>> entryIterator() {
18651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Iterator<Map.Entry<K, Collection<V>>> backingIterator =
18661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          multimap().asMap().entrySet().iterator();
18671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new Iterator<Multiset.Entry<K>>() {
18681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean hasNext() {
18691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return backingIterator.hasNext();
18701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
18711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Multiset.Entry<K> next() {
18731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          final Map.Entry<K, Collection<V>> backingEntry =
18741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              backingIterator.next();
18751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return new Multisets.AbstractEntry<K>() {
18761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override public K getElement() {
18771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return backingEntry.getKey();
18781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
18791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override public int getCount() {
18811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return backingEntry.getValue().size();
18821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
18831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          };
18841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
18851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public void remove() {
18871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          backingIterator.remove();
18881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
18891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
18901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
18911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override int distinctElements() {
18931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().asMap().size();
18941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
18951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override Set<Multiset.Entry<K>> createEntrySet() {
18971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new KeysEntrySet();
18981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
18991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class KeysEntrySet extends Multisets.EntrySet<K> {
19011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override Multiset<K> multiset() {
19021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Keys.this;
19031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Iterator<Multiset.Entry<K>> iterator() {
19061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return entryIterator();
19071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public int size() {
19101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return distinctElements();
19111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean isEmpty() {
19141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return multimap().isEmpty();
19151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean contains(@Nullable Object o) {
19181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (o instanceof Multiset.Entry<?>) {
19191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
19201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Collection<V> collection = multimap().asMap().get(entry.getElement());
19211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return collection != null && collection.size() == entry.getCount();
19221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
19231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
19241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean remove(@Nullable Object o) {
19271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (o instanceof Multiset.Entry<?>) {
19281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
19291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Collection<V> collection = multimap().asMap().get(entry.getElement());
19301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (collection != null && collection.size() == entry.getCount()) {
19311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            collection.clear();
19321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return true;
19331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
19341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
19351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
19361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
19381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean contains(@Nullable Object element) {
19401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().containsKey(element);
19411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
19421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Iterator<K> iterator() {
19441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Iterators.transform(multimap().entries().iterator(),
19451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          new Function<Map.Entry<K, V>, K>() {
19461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override public K apply(Map.Entry<K, V> entry) {
19471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return entry.getKey();
19481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
19491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          });
19501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
19511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int count(@Nullable Object element) {
19531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
19541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (multimap().containsKey(element)) {
19551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Collection<V> values = multimap().asMap().get(element);
19561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return (values == null) ? 0 : values.size();
19571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
19581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return 0;
19591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ClassCastException e) {
19601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return 0;
19611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (NullPointerException e) {
19621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return 0;
19631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
19651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int remove(@Nullable Object element, int occurrences) {
19671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkArgument(occurrences >= 0);
19681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (occurrences == 0) {
19691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return count(element);
19701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<V> values;
19731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
19741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        values = multimap().asMap().get(element);
19751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (ClassCastException e) {
19761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return 0;
19771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (NullPointerException e) {
19781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return 0;
19791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (values == null) {
19821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return 0;
19831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int oldCount = values.size();
19861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (occurrences >= oldCount) {
19871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        values.clear();
19881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } else {
19891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterator<V> iterator = values.iterator();
19901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        for (int i = 0; i < occurrences; i++) {
19911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          iterator.next();
19921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          iterator.remove();
19931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
19941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
19951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return oldCount;
19961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
19971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
19981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
19991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap().clear();
20001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<K> elementSet() {
20031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().keySet();
20041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
20061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static abstract class Values<K, V> extends AbstractCollection<V> {
20081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    abstract Multimap<K, V> multimap();
20091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Iterator<V> iterator() {
20111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final Iterator<Map.Entry<K, V>> backingIterator =
20121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          multimap().entries().iterator();
20131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new Iterator<V>() {
20141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean hasNext() {
20151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return backingIterator.hasNext();
20161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
20171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public V next() {
20191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return backingIterator.next().getValue();
20201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
20211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public void remove() {
20231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          backingIterator.remove();
20241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
20251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
20261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int size() {
20291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().size();
20301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean contains(@Nullable Object o) {
20331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().containsValue(o);
20341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
20371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap().clear();
20381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
20401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
20421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A skeleton implementation of {@link Multimap#entries()}.
20431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
20441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static abstract class Entries<K, V> extends
20451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      AbstractCollection<Map.Entry<K, V>> {
20461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    abstract Multimap<K, V> multimap();
20471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int size() {
20491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().size();
20501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean contains(@Nullable Object o) {
20531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (o instanceof Map.Entry<?, ?>) {
20541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
20551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return multimap().containsEntry(entry.getKey(), entry.getValue());
20561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
20571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
20581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean remove(@Nullable Object o) {
20611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (o instanceof Map.Entry<?, ?>) {
20621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
20631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return multimap().remove(entry.getKey(), entry.getValue());
20641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
20651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
20661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
20691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap().clear();
20701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
20721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
20741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A skeleton implementation of {@link SetMultimap#entries()}.
20751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
20761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static abstract class EntrySet<K, V> extends Entries<K, V> implements
20771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<Map.Entry<K, V>> {
20781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
20791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Sets.hashCodeImpl(this);
20801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(@Nullable Object obj) {
20831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Sets.equalsImpl(this, obj);
20841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
20851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
20861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
20881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A skeleton implementation of {@link Multimap#asMap()}.
20891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
20901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static abstract class AsMap<K, V> extends
20911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.ImprovedAbstractMap<K, Collection<V>> {
20921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    abstract Multimap<K, V> multimap();
20931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public abstract int size();
20951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    abstract Iterator<Entry<K, Collection<V>>> entryIterator();
20971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
20981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
20991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new EntrySet();
21001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    void removeValuesForKey(Object key){
21031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap().removeAll(key);
21041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class EntrySet extends Maps.EntrySet<K, Collection<V>> {
21071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override Map<K, Collection<V>> map() {
21081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return AsMap.this;
21091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
21101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Iterator<Entry<K, Collection<V>>> iterator() {
21121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return entryIterator();
21131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
21141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean remove(Object o) {
21161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (!contains(o)) {
21171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
21181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
21191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
21201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        removeValuesForKey(entry.getKey());
21211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return true;
21221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
21231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
21261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> get(Object key) {
21271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return containsKey(key) ? multimap().get((K) key) : null;
21281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> remove(Object key) {
21311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return containsKey(key) ? multimap().removeAll(key) : null;
21321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<K> keySet() {
21351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().keySet();
21361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean isEmpty() {
21391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().isEmpty();
21401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsKey(Object key) {
21431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return multimap().containsKey(key);
21441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
21471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap().clear();
21481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
21491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
21501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
21521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a multimap containing the mappings in {@code unfiltered} whose keys
21531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * satisfy a predicate. The returned multimap is a live view of
21541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code unfiltered}; changes to one affect the other.
21551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
21561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The resulting multimap's views have iterators that don't support
21571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code remove()}, but all other methods are supported by the multimap and
21581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * its views. When adding a key that doesn't satisfy the predicate, the
21591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods
21601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * throw an {@link IllegalArgumentException}.
21611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
21621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
21631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the filtered multimap or its views, only mappings whose keys satisfy the
21641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * filter will be removed from the underlying multimap.
21651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
21661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap isn't threadsafe or serializable, even if
21671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code unfiltered} is.
21681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
21691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
21701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * across every key/value mapping in the underlying multimap and determine
21711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * which satisfy the filter. When a live view is <i>not</i> needed, it may be
21721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * faster to copy the filtered multimap and use the copy.
21731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
21741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
21751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * as documented at {@link Predicate#apply}. Do not provide a predicate such
21761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
21771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * with equals.
21781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
21791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 11.0
21801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
21811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
21821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible(value = "untested")
21831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> Multimap<K, V> filterKeys(
21841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
21851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(keyPredicate);
21861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Predicate<Entry<K, V>> entryPredicate =
21871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Predicate<Entry<K, V>>() {
21881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
21891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public boolean apply(Entry<K, V> input) {
21901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return keyPredicate.apply(input.getKey());
21911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
21921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
21931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return filterEntries(unfiltered, entryPredicate);
21941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
21951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
21971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a multimap containing the mappings in {@code unfiltered} whose values
21981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * satisfy a predicate. The returned multimap is a live view of
21991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code unfiltered}; changes to one affect the other.
22001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The resulting multimap's views have iterators that don't support
22021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code remove()}, but all other methods are supported by the multimap and
22031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * its views. When adding a value that doesn't satisfy the predicate, the
22041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods
22051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * throw an {@link IllegalArgumentException}.
22061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
22081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the filtered multimap or its views, only mappings whose value satisfy the
22091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * filter will be removed from the underlying multimap.
22101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap isn't threadsafe or serializable, even if
22121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code unfiltered} is.
22131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
22151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * across every key/value mapping in the underlying multimap and determine
22161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * which satisfy the filter. When a live view is <i>not</i> needed, it may be
22171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * faster to copy the filtered multimap and use the copy.
22181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
22201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
22211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
22221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * inconsistent with equals.
22231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 11.0
22251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
22261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
22271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible(value = "untested")
22281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> Multimap<K, V> filterValues(
22291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
22301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(valuePredicate);
22311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Predicate<Entry<K, V>> entryPredicate =
22321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Predicate<Entry<K, V>>() {
22331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
22341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public boolean apply(Entry<K, V> input) {
22351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return valuePredicate.apply(input.getValue());
22361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
22371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
22381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return filterEntries(unfiltered, entryPredicate);
22391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
22401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
22411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
22421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a multimap containing the mappings in {@code unfiltered} that
22431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * satisfy a predicate. The returned multimap is a live view of
22441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code unfiltered}; changes to one affect the other.
22451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The resulting multimap's views have iterators that don't support
22471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code remove()}, but all other methods are supported by the multimap and
22481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * its views. When adding a key/value pair that doesn't satisfy the predicate,
22491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods
22501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * throw an {@link IllegalArgumentException}.
22511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
22531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the filtered multimap or its views, only mappings whose keys satisfy the
22541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * filter will be removed from the underlying multimap.
22551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multimap isn't threadsafe or serializable, even if
22571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code unfiltered} is.
22581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
22601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * across every key/value mapping in the underlying multimap and determine
22611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * which satisfy the filter. When a live view is <i>not</i> needed, it may be
22621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * faster to copy the filtered multimap and use the copy.
22631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
22651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * equals</i>, as documented at {@link Predicate#apply}.
22661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
22671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 11.0
22681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
22691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
22701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible(value = "untested")
22711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> Multimap<K, V> filterEntries(
22721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
22731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(entryPredicate);
22741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (unfiltered instanceof FilteredMultimap)
22751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate)
22761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        : new FilteredMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
22771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
22781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
22791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
22801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Support removal operations when filtering a filtered multimap. Since a
22811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * filtered multimap has iterators that don't support remove, passing one to
22821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the FilteredMultimap constructor would lead to a multimap whose removal
22831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * operations would fail. This method combines the predicates to avoid that
22841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * problem.
22851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
22861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> map,
22871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Predicate<? super Entry<K, V>> entryPredicate) {
22881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Predicate<Entry<K, V>> predicate
22891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Predicates.and(map.predicate, entryPredicate);
22901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new FilteredMultimap<K, V>(map.unfiltered, predicate);
22911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
22921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
22931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class FilteredMultimap<K, V> implements Multimap<K, V> {
22941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Multimap<K, V> unfiltered;
22951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Predicate<? super Entry<K, V>> predicate;
22961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
22971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    FilteredMultimap(Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
22981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.unfiltered = unfiltered;
22991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.predicate = predicate;
23001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int size() {
23031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return entries().size();
23041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean isEmpty() {
23071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return entries().isEmpty();
23081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsKey(Object key) {
23111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return asMap().containsKey(key);
23121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsValue(Object value) {
23151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return values().contains(value);
23161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // This method should be called only when key is a K and value is a V.
23191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
23201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean satisfiesPredicate(Object key, Object value) {
23211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return predicate.apply(Maps.immutableEntry((K) key, (V) value));
23221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsEntry(Object key, Object value) {
23251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return unfiltered.containsEntry(key, value) && satisfiesPredicate(key, value);
23261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean put(K key, V value) {
23291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkArgument(satisfiesPredicate(key, value));
23301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return unfiltered.put(key, value);
23311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean remove(Object key, Object value) {
23341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return containsEntry(key, value) ? unfiltered.remove(key, value) : false;
23351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean putAll(K key, Iterable<? extends V> values) {
23381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (V value : values) {
23391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkArgument(satisfiesPredicate(key, value));
23401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
23411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return unfiltered.putAll(key, values);
23421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
23451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (Entry<? extends K, ? extends V> entry : multimap.entries()) {
23461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkArgument(satisfiesPredicate(entry.getKey(), entry.getValue()));
23471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
23481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return unfiltered.putAll(multimap);
23491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
23521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (V value : values) {
23531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkArgument(satisfiesPredicate(key, value));
23541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
23551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Not calling unfiltered.replaceValues() since values that don't satisify
23561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // the filter should remain in the multimap.
23571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<V> oldValues = removeAll(key);
23581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unfiltered.putAll(key, values);
23591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return oldValues;
23601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> removeAll(Object key) {
23631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      List<V> removed = Lists.newArrayList();
23641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<V> values = unfiltered.asMap().get(key);
23651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (values != null) {
23661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterator<V> iterator = values.iterator();
23671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        while (iterator.hasNext()) {
23681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          V value = iterator.next();
23691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (satisfiesPredicate(key, value)) {
23701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            removed.add(value);
23711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            iterator.remove();
23721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
23731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
23741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
23751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (unfiltered instanceof SetMultimap) {
23761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Collections.unmodifiableSet(Sets.newLinkedHashSet(removed));
23771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } else {
23781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Collections.unmodifiableList(removed);
23791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
23801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
23831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entries().clear();
23841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(@Nullable Object object) {
23871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (object == this) {
23881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return true;
23891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
23901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (object instanceof Multimap) {
23911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Multimap<?, ?> that = (Multimap<?, ?>) object;
23921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return asMap().equals(that.asMap());
23931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
23941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
23951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
23961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
23971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
23981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return asMap().hashCode();
23991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
24021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return asMap().toString();
24031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class ValuePredicate implements Predicate<V> {
24061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final K key;
24071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ValuePredicate(K key) {
24081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        this.key = key;
24091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean apply(V value) {
24111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return satisfiesPredicate(key, value);
24121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<V> filterCollection(Collection<V> collection, Predicate<V> predicate) {
24161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (collection instanceof Set) {
24171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Sets.filter((Set<V>) collection, predicate);
24181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } else {
24191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Collections2.filter(collection, predicate);
24201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> get(K key) {
24241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return filterCollection(unfiltered.get(key), new ValuePredicate(key));
24251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<K> keySet() {
24281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return asMap().keySet();
24291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<V> values;
24321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> values() {
24341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (values == null) ? values = new Values() : values;
24351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class Values extends Multimaps.Values<K, V> {
24381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override Multimap<K, V> multimap() {
24391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return FilteredMultimap.this;
24401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean contains(@Nullable Object o) {
24431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Iterators.contains(iterator(), o);
24441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Override remove methods since iterator doesn't support remove.
24471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean remove(Object o) {
24491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
24501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        while (iterator.hasNext()) {
24511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Entry<K, V> entry = iterator.next();
24521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) {
24531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            iterator.remove();
24541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return true;
24551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
24561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
24571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
24581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean removeAll(Collection<?> c) {
24611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean changed = false;
24621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
24631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        while (iterator.hasNext()) {
24641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Entry<K, V> entry = iterator.next();
24651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (c.contains(entry.getValue()) && predicate.apply(entry)) {
24661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            iterator.remove();
24671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            changed = true;
24681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
24691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
24701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return changed;
24711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean retainAll(Collection<?> c) {
24741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        boolean changed = false;
24751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
24761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        while (iterator.hasNext()) {
24771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Entry<K, V> entry = iterator.next();
24781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (!c.contains(entry.getValue()) && predicate.apply(entry)) {
24791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            iterator.remove();
24801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            changed = true;
24811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
24821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
24831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return changed;
24841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
24851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<Entry<K, V>> entries;
24881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<Entry<K, V>> entries() {
24901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (entries == null)
24911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          ? entries = Collections2.filter(unfiltered.entries(), predicate)
24921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          : entries;
24931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
24941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
24961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Remove all filtered asMap() entries that satisfy the predicate.
24971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
24981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean removeEntriesIf(Predicate<Map.Entry<K, Collection<V>>> removalPredicate) {
24991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Iterator<Map.Entry<K, Collection<V>>> iterator = unfiltered.asMap().entrySet().iterator();
25001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean changed = false;
25011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      while (iterator.hasNext()) {
25021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // Determine whether to remove the filtered values with this key.
25031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Map.Entry<K, Collection<V>> entry = iterator.next();
25041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        K key = entry.getKey();
25051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<V> collection = entry.getValue();
25061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Predicate<V> valuePredicate = new ValuePredicate(key);
25071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<V> filteredCollection = filterCollection(collection, valuePredicate);
25081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Map.Entry<K, Collection<V>> filteredEntry = Maps.immutableEntry(key, filteredCollection);
25091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (removalPredicate.apply(filteredEntry) && !filteredCollection.isEmpty()) {
25101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          changed = true;
25111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (Iterables.all(collection, valuePredicate)) {
25121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            iterator.remove();  // Remove all values for the key.
25131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          } else {
25141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            filteredCollection.clear();  // Remove the filtered values only.
25151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
25161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
25171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
25181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return changed;
25191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
25201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<K, Collection<V>> asMap;
25221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<K, Collection<V>> asMap() {
25241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (asMap == null) ? asMap = createAsMap() : asMap;
25251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
25261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    static final Predicate<Collection<?>> NOT_EMPTY = new Predicate<Collection<?>>() {
25281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean apply(Collection<?> input) {
25291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return !input.isEmpty();
25301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
25311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
25321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<K, Collection<V>> createAsMap() {
25341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Select the values that satisify the predicate.
25351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      EntryTransformer<K, Collection<V>, Collection<V>> transformer
25361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          = new EntryTransformer<K, Collection<V>, Collection<V>>() {
25371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override public Collection<V> transformEntry(K key, Collection<V> collection) {
25381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return filterCollection(collection, new ValuePredicate(key));
25391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
25401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
25411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> transformed
25421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          = Maps.transformEntries(unfiltered.asMap(), transformer);
25431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Select the keys that have at least one value remaining.
25451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<K, Collection<V>> filtered = Maps.filterValues(transformed, NOT_EMPTY);
25461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Override the removal methods, since removing a map entry should not
25481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // affect values that don't satisfy the filter.
25491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new AsMap(filtered);
25501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
25511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class AsMap extends ForwardingMap<K, Collection<V>> {
25531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     final Map<K, Collection<V>> delegate;
25541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      AsMap(Map<K, Collection<V>> delegate) {
25561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        this.delegate = delegate;
25571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
25581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override protected Map<K, Collection<V>> delegate() {
25601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return delegate;
25611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
25621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Collection<V> remove(Object o) {
25641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<V> output = FilteredMultimap.this.removeAll(o);
25651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return output.isEmpty() ? null : output;
25661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
25671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public void clear() {
25691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        FilteredMultimap.this.clear();
25701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
25711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<K> keySet;
25731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Set<K> keySet() {
25751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (keySet == null) ? keySet = new KeySet() : keySet;
25761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
25771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      class KeySet extends Maps.KeySet<K, Collection<V>> {
25791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override Map<K, Collection<V>> map() {
25801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return AsMap.this;
25811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
25821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean remove(Object o) {
25841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert           Collection<V> collection = delegate.get(o);
25851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert           if (collection == null) {
25861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert             return false;
25871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert           }
25881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert           collection.clear();
25891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert           return true;
25901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
25911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean removeAll(Collection<?> c) {
25931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return Sets.removeAllImpl(this, c);
25941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
25951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
25961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean retainAll(final Collection<?> c) {
25971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Predicate<Map.Entry<K, Collection<V>>> removalPredicate
25981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              = new Predicate<Map.Entry<K, Collection<V>>>() {
25991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
26001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  return !c.contains(entry.getKey());
26011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                }
26021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              };
26031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return removeEntriesIf(removalPredicate);
26041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
26061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Values asMapValues;
26081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Collection<Collection<V>> values() {
26101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (asMapValues == null) ? asMapValues = new Values() : asMapValues;
26111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
26121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      class Values extends Maps.Values<K, Collection<V>> {
26141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override Map<K, Collection<V>> map() {
26151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return AsMap.this;
26161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean remove(Object o) {
26191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          for (Collection<V> collection : this) {
26201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            if (collection.equals(o)) {
26211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              collection.clear();
26221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return true;
26231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
26241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
26251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
26261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean removeAll(final Collection<?> c) {
26291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Predicate<Map.Entry<K, Collection<V>>> removalPredicate
26301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              = new Predicate<Map.Entry<K, Collection<V>>>() {
26311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
26321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  return c.contains(entry.getValue());
26331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                }
26341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              };
26351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return removeEntriesIf(removalPredicate);
26361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean retainAll(final Collection<?> c) {
26391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Predicate<Map.Entry<K, Collection<V>>> removalPredicate
26401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              = new Predicate<Map.Entry<K, Collection<V>>>() {
26411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
26421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  return !c.contains(entry.getValue());
26431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                }
26441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              };
26451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return removeEntriesIf(removalPredicate);
26461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
26481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      EntrySet entrySet;
26501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
26521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return (entrySet == null) ? entrySet = new EntrySet(super.entrySet()) : entrySet;
26531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
26541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      class EntrySet extends Maps.EntrySet<K, Collection<V>> {
26561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Set<Map.Entry<K, Collection<V>>> delegateEntries;
26571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public EntrySet(Set<Map.Entry<K, Collection<V>>> delegateEntries) {
26591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          this.delegateEntries = delegateEntries;
26601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override Map<K, Collection<V>> map() {
26631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return AsMap.this;
26641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
26671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegateEntries.iterator();
26681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean remove(Object o) {
26711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (o instanceof Entry<?, ?>) {
26721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Entry<?, ?> entry = (Entry<?, ?>) o;
26731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Collection<V> collection = delegate.get(entry.getKey());
26741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            if (collection != null && collection.equals(entry.getValue())) {
26751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              collection.clear();
26761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return true;
26771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
26781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
26791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
26801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean removeAll(Collection<?> c) {
26831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return Sets.removeAllImpl(this, c);
26841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean retainAll(final Collection<?> c) {
26871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Predicate<Map.Entry<K, Collection<V>>> removalPredicate
26881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              = new Predicate<Map.Entry<K, Collection<V>>>() {
26891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
26901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  return !c.contains(entry);
26911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                }
26921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              };
26931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return removeEntriesIf(removalPredicate);
26941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
26951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
26961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
26971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    AbstractMultiset<K> keys;
26991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
27001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Multiset<K> keys() {
27011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (keys == null) ? keys = new Keys() : keys;
27021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
27031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
27041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class Keys extends Multimaps.Keys<K, V> {
27051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override Multimap<K, V> multimap() {
27061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return FilteredMultimap.this;
27071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
27081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
27091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public int remove(Object o, int occurrences) {
27101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkArgument(occurrences >= 0);
27111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<V> values = unfiltered.asMap().get(o);
27121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (values == null) {
27131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return 0;
27141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
27151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int priorCount = 0;
27161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int removed = 0;
27171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterator<V> iterator = values.iterator();
27181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        while (iterator.hasNext()) {
27191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (satisfiesPredicate(o, iterator.next())) {
27201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            priorCount++;
27211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            if (removed < occurrences) {
27221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              iterator.remove();
27231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              removed++;
27241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
27251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
27261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
27271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return priorCount;
27281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
27291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
27301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override Set<Multiset.Entry<K>> createEntrySet() {
27311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return new EntrySet();
27321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
27331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
27341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      class EntrySet extends Multimaps.Keys<K, V>.KeysEntrySet {
27351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean removeAll(Collection<?> c) {
27361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return Sets.removeAllImpl(this, c);
27371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
27381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
27391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean retainAll(final Collection<?> c) {
27401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Predicate<Map.Entry<K, Collection<V>>> removalPredicate
27411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              = new Predicate<Map.Entry<K, Collection<V>>>() {
27421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
27431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  Multiset.Entry<K> multisetEntry
27441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                      = Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
27451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  return !c.contains(multisetEntry);
27461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                }
27471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              };
27481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return removeEntriesIf(removalPredicate);
27491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
27501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
27511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
27521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
27531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
27541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // TODO(jlevy): Create methods that filter a SetMultimap or SortedSetMultimap.
27551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
2756