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