001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkArgument;
020import static com.google.common.base.Preconditions.checkNotNull;
021import static com.google.common.base.Predicates.compose;
022import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
023import static com.google.common.collect.CollectPreconditions.checkNonnegative;
024
025import com.google.common.annotations.Beta;
026import com.google.common.annotations.GwtCompatible;
027import com.google.common.annotations.GwtIncompatible;
028import com.google.common.base.Converter;
029import com.google.common.base.Equivalence;
030import com.google.common.base.Function;
031import com.google.common.base.Objects;
032import com.google.common.base.Preconditions;
033import com.google.common.base.Predicate;
034import com.google.common.base.Predicates;
035import com.google.common.collect.MapDifference.ValueDifference;
036import com.google.common.primitives.Ints;
037import com.google.errorprone.annotations.CanIgnoreReturnValue;
038import com.google.j2objc.annotations.RetainedWith;
039import com.google.j2objc.annotations.Weak;
040import com.google.j2objc.annotations.WeakOuter;
041import java.io.Serializable;
042import java.util.AbstractCollection;
043import java.util.AbstractMap;
044import java.util.Collection;
045import java.util.Collections;
046import java.util.Comparator;
047import java.util.EnumMap;
048import java.util.Enumeration;
049import java.util.HashMap;
050import java.util.IdentityHashMap;
051import java.util.Iterator;
052import java.util.LinkedHashMap;
053import java.util.Map;
054import java.util.Map.Entry;
055import java.util.NavigableMap;
056import java.util.NavigableSet;
057import java.util.Properties;
058import java.util.Set;
059import java.util.SortedMap;
060import java.util.SortedSet;
061import java.util.TreeMap;
062import java.util.concurrent.ConcurrentHashMap;
063import java.util.concurrent.ConcurrentMap;
064import org.checkerframework.checker.nullness.compatqual.MonotonicNonNullDecl;
065import org.checkerframework.checker.nullness.compatqual.NullableDecl;
066
067/**
068 * Static utility methods pertaining to {@link Map} instances (including instances of {@link
069 * SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts {@link Lists}, {@link Sets}
070 * and {@link Queues}.
071 *
072 * <p>See the Guava User Guide article on <a href=
073 * "https://github.com/google/guava/wiki/CollectionUtilitiesExplained#maps"> {@code Maps}</a>.
074 *
075 * @author Kevin Bourrillion
076 * @author Mike Bostock
077 * @author Isaac Shum
078 * @author Louis Wasserman
079 * @since 2.0
080 */
081@GwtCompatible(emulated = true)
082public final class Maps {
083  private Maps() {}
084
085  private enum EntryFunction implements Function<Entry<?, ?>, Object> {
086    KEY {
087      @Override
088      @NullableDecl
089      public Object apply(Entry<?, ?> entry) {
090        return entry.getKey();
091      }
092    },
093    VALUE {
094      @Override
095      @NullableDecl
096      public Object apply(Entry<?, ?> entry) {
097        return entry.getValue();
098      }
099    };
100  }
101
102  @SuppressWarnings("unchecked")
103  static <K> Function<Entry<K, ?>, K> keyFunction() {
104    return (Function) EntryFunction.KEY;
105  }
106
107  @SuppressWarnings("unchecked")
108  static <V> Function<Entry<?, V>, V> valueFunction() {
109    return (Function) EntryFunction.VALUE;
110  }
111
112  static <K, V> Iterator<K> keyIterator(Iterator<Entry<K, V>> entryIterator) {
113    return new TransformedIterator<Entry<K, V>, K>(entryIterator) {
114      @Override
115      K transform(Entry<K, V> entry) {
116        return entry.getKey();
117      }
118    };
119  }
120
121  static <K, V> Iterator<V> valueIterator(Iterator<Entry<K, V>> entryIterator) {
122    return new TransformedIterator<Entry<K, V>, V>(entryIterator) {
123      @Override
124      V transform(Entry<K, V> entry) {
125        return entry.getValue();
126      }
127    };
128  }
129
130  /**
131   * Returns an immutable map instance containing the given entries. Internally, the returned map
132   * will be backed by an {@link EnumMap}.
133   *
134   * <p>The iteration order of the returned map follows the enum's iteration order, not the order in
135   * which the elements appear in the given map.
136   *
137   * @param map the map to make an immutable copy of
138   * @return an immutable map containing those entries
139   * @since 14.0
140   */
141  @GwtCompatible(serializable = true)
142  public static <K extends Enum<K>, V> ImmutableMap<K, V> immutableEnumMap(
143      Map<K, ? extends V> map) {
144    if (map instanceof ImmutableEnumMap) {
145      @SuppressWarnings("unchecked") // safe covariant cast
146      ImmutableEnumMap<K, V> result = (ImmutableEnumMap<K, V>) map;
147      return result;
148    }
149    Iterator<? extends Entry<K, ? extends V>> entryItr = map.entrySet().iterator();
150    if (!entryItr.hasNext()) {
151      return ImmutableMap.of();
152    }
153    Entry<K, ? extends V> entry1 = entryItr.next();
154    K key1 = entry1.getKey();
155    V value1 = entry1.getValue();
156    checkEntryNotNull(key1, value1);
157    Class<K> clazz = key1.getDeclaringClass();
158    EnumMap<K, V> enumMap = new EnumMap<>(clazz);
159    enumMap.put(key1, value1);
160    while (entryItr.hasNext()) {
161      Entry<K, ? extends V> entry = entryItr.next();
162      K key = entry.getKey();
163      V value = entry.getValue();
164      checkEntryNotNull(key, value);
165      enumMap.put(key, value);
166    }
167    return ImmutableEnumMap.asImmutable(enumMap);
168  }
169
170  /**
171   * Creates a <i>mutable</i>, empty {@code HashMap} instance.
172   *
173   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#of()} instead.
174   *
175   * <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link #newEnumMap} instead.
176   *
177   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
178   * deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new
179   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
180   *
181   * @return a new, empty {@code HashMap}
182   */
183  public static <K, V> HashMap<K, V> newHashMap() {
184    return new HashMap<>();
185  }
186
187  /**
188   * Creates a <i>mutable</i> {@code HashMap} instance with the same mappings as the specified map.
189   *
190   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#copyOf(Map)} instead.
191   *
192   * <p><b>Note:</b> if {@code K} is an {@link Enum} type, use {@link #newEnumMap} instead.
193   *
194   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
195   * deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new
196   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
197   *
198   * @param map the mappings to be placed in the new map
199   * @return a new {@code HashMap} initialized with the mappings from {@code map}
200   */
201  public static <K, V> HashMap<K, V> newHashMap(Map<? extends K, ? extends V> map) {
202    return new HashMap<>(map);
203  }
204
205  /**
206   * Creates a {@code HashMap} instance, with a high enough "initial capacity" that it <i>should</i>
207   * hold {@code expectedSize} elements without growth. This behavior cannot be broadly guaranteed,
208   * but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed that the method
209   * isn't inadvertently <i>oversizing</i> the returned map.
210   *
211   * @param expectedSize the number of entries you expect to add to the returned map
212   * @return a new, empty {@code HashMap} with enough capacity to hold {@code expectedSize} entries
213   *     without resizing
214   * @throws IllegalArgumentException if {@code expectedSize} is negative
215   */
216  public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) {
217    return new HashMap<>(capacity(expectedSize));
218  }
219
220  /**
221   * Returns a capacity that is sufficient to keep the map from being resized as long as it grows no
222   * larger than expectedSize and the load factor is ≥ its default (0.75).
223   */
224  static int capacity(int expectedSize) {
225    if (expectedSize < 3) {
226      checkNonnegative(expectedSize, "expectedSize");
227      return expectedSize + 1;
228    }
229    if (expectedSize < Ints.MAX_POWER_OF_TWO) {
230      // This is the calculation used in JDK8 to resize when a putAll
231      // happens; it seems to be the most conservative calculation we
232      // can make.  0.75 is the default load factor.
233      return (int) ((float) expectedSize / 0.75F + 1.0F);
234    }
235    return Integer.MAX_VALUE; // any large value
236  }
237
238  /**
239   * Creates a <i>mutable</i>, empty, insertion-ordered {@code LinkedHashMap} instance.
240   *
241   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#of()} instead.
242   *
243   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
244   * deprecated. Instead, use the {@code LinkedHashMap} constructor directly, taking advantage of
245   * the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
246   *
247   * @return a new, empty {@code LinkedHashMap}
248   */
249  public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
250    return new LinkedHashMap<>();
251  }
252
253  /**
254   * Creates a <i>mutable</i>, insertion-ordered {@code LinkedHashMap} instance with the same
255   * mappings as the specified map.
256   *
257   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#copyOf(Map)} instead.
258   *
259   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
260   * deprecated. Instead, use the {@code LinkedHashMap} constructor directly, taking advantage of
261   * the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
262   *
263   * @param map the mappings to be placed in the new map
264   * @return a new, {@code LinkedHashMap} initialized with the mappings from {@code map}
265   */
266  public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map) {
267    return new LinkedHashMap<>(map);
268  }
269
270  /**
271   * Creates a {@code LinkedHashMap} instance, with a high enough "initial capacity" that it
272   * <i>should</i> hold {@code expectedSize} elements without growth. This behavior cannot be
273   * broadly guaranteed, but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed
274   * that the method isn't inadvertently <i>oversizing</i> the returned map.
275   *
276   * @param expectedSize the number of entries you expect to add to the returned map
277   * @return a new, empty {@code LinkedHashMap} with enough capacity to hold {@code expectedSize}
278   *     entries without resizing
279   * @throws IllegalArgumentException if {@code expectedSize} is negative
280   * @since 19.0
281   */
282  public static <K, V> LinkedHashMap<K, V> newLinkedHashMapWithExpectedSize(int expectedSize) {
283    return new LinkedHashMap<>(capacity(expectedSize));
284  }
285
286  /**
287   * Creates a new empty {@link ConcurrentHashMap} instance.
288   *
289   * @since 3.0
290   */
291  public static <K, V> ConcurrentMap<K, V> newConcurrentMap() {
292    return new ConcurrentHashMap<>();
293  }
294
295  /**
296   * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the natural ordering of its
297   * elements.
298   *
299   * <p><b>Note:</b> if mutability is not required, use {@link ImmutableSortedMap#of()} instead.
300   *
301   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
302   * deprecated. Instead, use the {@code TreeMap} constructor directly, taking advantage of the new
303   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
304   *
305   * @return a new, empty {@code TreeMap}
306   */
307  public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
308    return new TreeMap<>();
309  }
310
311  /**
312   * Creates a <i>mutable</i> {@code TreeMap} instance with the same mappings as the specified map
313   * and using the same ordering as the specified map.
314   *
315   * <p><b>Note:</b> if mutability is not required, use {@link
316   * ImmutableSortedMap#copyOfSorted(SortedMap)} instead.
317   *
318   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
319   * deprecated. Instead, use the {@code TreeMap} constructor directly, taking advantage of the new
320   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
321   *
322   * @param map the sorted map whose mappings are to be placed in the new map and whose comparator
323   *     is to be used to sort the new map
324   * @return a new {@code TreeMap} initialized with the mappings from {@code map} and using the
325   *     comparator of {@code map}
326   */
327  public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map) {
328    return new TreeMap<>(map);
329  }
330
331  /**
332   * Creates a <i>mutable</i>, empty {@code TreeMap} instance using the given comparator.
333   *
334   * <p><b>Note:</b> if mutability is not required, use {@code
335   * ImmutableSortedMap.orderedBy(comparator).build()} instead.
336   *
337   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
338   * deprecated. Instead, use the {@code TreeMap} constructor directly, taking advantage of the new
339   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
340   *
341   * @param comparator the comparator to sort the keys with
342   * @return a new, empty {@code TreeMap}
343   */
344  public static <C, K extends C, V> TreeMap<K, V> newTreeMap(
345      @NullableDecl Comparator<C> comparator) {
346    // Ideally, the extra type parameter "C" shouldn't be necessary. It is a
347    // work-around of a compiler type inference quirk that prevents the
348    // following code from being compiled:
349    // Comparator<Class<?>> comparator = null;
350    // Map<Class<? extends Throwable>, String> map = newTreeMap(comparator);
351    return new TreeMap<>(comparator);
352  }
353
354  /**
355   * Creates an {@code EnumMap} instance.
356   *
357   * @param type the key type for this map
358   * @return a new, empty {@code EnumMap}
359   */
360  public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Class<K> type) {
361    return new EnumMap<>(checkNotNull(type));
362  }
363
364  /**
365   * Creates an {@code EnumMap} with the same mappings as the specified map.
366   *
367   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
368   * deprecated. Instead, use the {@code EnumMap} constructor directly, taking advantage of the new
369   * <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
370   *
371   * @param map the map from which to initialize this {@code EnumMap}
372   * @return a new {@code EnumMap} initialized with the mappings from {@code map}
373   * @throws IllegalArgumentException if {@code m} is not an {@code EnumMap} instance and contains
374   *     no mappings
375   */
376  public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(Map<K, ? extends V> map) {
377    return new EnumMap<>(map);
378  }
379
380  /**
381   * Creates an {@code IdentityHashMap} instance.
382   *
383   * <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
384   * deprecated. Instead, use the {@code IdentityHashMap} constructor directly, taking advantage of
385   * the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
386   *
387   * @return a new, empty {@code IdentityHashMap}
388   */
389  public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
390    return new IdentityHashMap<>();
391  }
392
393  /**
394   * Computes the difference between two maps. This difference is an immutable snapshot of the state
395   * of the maps at the time this method is called. It will never change, even if the maps change at
396   * a later time.
397   *
398   * <p>Since this method uses {@code HashMap} instances internally, the keys of the supplied maps
399   * must be well-behaved with respect to {@link Object#equals} and {@link Object#hashCode}.
400   *
401   * <p><b>Note:</b>If you only need to know whether two maps have the same mappings, call {@code
402   * left.equals(right)} instead of this method.
403   *
404   * @param left the map to treat as the "left" map for purposes of comparison
405   * @param right the map to treat as the "right" map for purposes of comparison
406   * @return the difference between the two maps
407   */
408  @SuppressWarnings("unchecked")
409  public static <K, V> MapDifference<K, V> difference(
410      Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) {
411    if (left instanceof SortedMap) {
412      SortedMap<K, ? extends V> sortedLeft = (SortedMap<K, ? extends V>) left;
413      return difference(sortedLeft, right);
414    }
415    return difference(left, right, Equivalence.equals());
416  }
417
418  /**
419   * Computes the difference between two maps. This difference is an immutable snapshot of the state
420   * of the maps at the time this method is called. It will never change, even if the maps change at
421   * a later time.
422   *
423   * <p>Since this method uses {@code HashMap} instances internally, the keys of the supplied maps
424   * must be well-behaved with respect to {@link Object#equals} and {@link Object#hashCode}.
425   *
426   * @param left the map to treat as the "left" map for purposes of comparison
427   * @param right the map to treat as the "right" map for purposes of comparison
428   * @param valueEquivalence the equivalence relationship to use to compare values
429   * @return the difference between the two maps
430   * @since 10.0
431   */
432  public static <K, V> MapDifference<K, V> difference(
433      Map<? extends K, ? extends V> left,
434      Map<? extends K, ? extends V> right,
435      Equivalence<? super V> valueEquivalence) {
436    Preconditions.checkNotNull(valueEquivalence);
437
438    Map<K, V> onlyOnLeft = newLinkedHashMap();
439    Map<K, V> onlyOnRight = new LinkedHashMap<>(right); // will whittle it down
440    Map<K, V> onBoth = newLinkedHashMap();
441    Map<K, MapDifference.ValueDifference<V>> differences = newLinkedHashMap();
442    doDifference(left, right, valueEquivalence, onlyOnLeft, onlyOnRight, onBoth, differences);
443    return new MapDifferenceImpl<>(onlyOnLeft, onlyOnRight, onBoth, differences);
444  }
445
446  /**
447   * Computes the difference between two sorted maps, using the comparator of the left map, or
448   * {@code Ordering.natural()} if the left map uses the natural ordering of its elements. This
449   * difference is an immutable snapshot of the state of the maps at the time this method is called.
450   * It will never change, even if the maps change at a later time.
451   *
452   * <p>Since this method uses {@code TreeMap} instances internally, the keys of the right map must
453   * all compare as distinct according to the comparator of the left map.
454   *
455   * <p><b>Note:</b>If you only need to know whether two sorted maps have the same mappings, call
456   * {@code left.equals(right)} instead of this method.
457   *
458   * @param left the map to treat as the "left" map for purposes of comparison
459   * @param right the map to treat as the "right" map for purposes of comparison
460   * @return the difference between the two maps
461   * @since 11.0
462   */
463  public static <K, V> SortedMapDifference<K, V> difference(
464      SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) {
465    checkNotNull(left);
466    checkNotNull(right);
467    Comparator<? super K> comparator = orNaturalOrder(left.comparator());
468    SortedMap<K, V> onlyOnLeft = Maps.newTreeMap(comparator);
469    SortedMap<K, V> onlyOnRight = Maps.newTreeMap(comparator);
470    onlyOnRight.putAll(right); // will whittle it down
471    SortedMap<K, V> onBoth = Maps.newTreeMap(comparator);
472    SortedMap<K, MapDifference.ValueDifference<V>> differences = Maps.newTreeMap(comparator);
473    doDifference(left, right, Equivalence.equals(), onlyOnLeft, onlyOnRight, onBoth, differences);
474    return new SortedMapDifferenceImpl<>(onlyOnLeft, onlyOnRight, onBoth, differences);
475  }
476
477  private static <K, V> void doDifference(
478      Map<? extends K, ? extends V> left,
479      Map<? extends K, ? extends V> right,
480      Equivalence<? super V> valueEquivalence,
481      Map<K, V> onlyOnLeft,
482      Map<K, V> onlyOnRight,
483      Map<K, V> onBoth,
484      Map<K, MapDifference.ValueDifference<V>> differences) {
485    for (Entry<? extends K, ? extends V> entry : left.entrySet()) {
486      K leftKey = entry.getKey();
487      V leftValue = entry.getValue();
488      if (right.containsKey(leftKey)) {
489        V rightValue = onlyOnRight.remove(leftKey);
490        if (valueEquivalence.equivalent(leftValue, rightValue)) {
491          onBoth.put(leftKey, leftValue);
492        } else {
493          differences.put(leftKey, ValueDifferenceImpl.create(leftValue, rightValue));
494        }
495      } else {
496        onlyOnLeft.put(leftKey, leftValue);
497      }
498    }
499  }
500
501  private static <K, V> Map<K, V> unmodifiableMap(Map<K, ? extends V> map) {
502    if (map instanceof SortedMap) {
503      return Collections.unmodifiableSortedMap((SortedMap<K, ? extends V>) map);
504    } else {
505      return Collections.unmodifiableMap(map);
506    }
507  }
508
509  static class MapDifferenceImpl<K, V> implements MapDifference<K, V> {
510    final Map<K, V> onlyOnLeft;
511    final Map<K, V> onlyOnRight;
512    final Map<K, V> onBoth;
513    final Map<K, ValueDifference<V>> differences;
514
515    MapDifferenceImpl(
516        Map<K, V> onlyOnLeft,
517        Map<K, V> onlyOnRight,
518        Map<K, V> onBoth,
519        Map<K, ValueDifference<V>> differences) {
520      this.onlyOnLeft = unmodifiableMap(onlyOnLeft);
521      this.onlyOnRight = unmodifiableMap(onlyOnRight);
522      this.onBoth = unmodifiableMap(onBoth);
523      this.differences = unmodifiableMap(differences);
524    }
525
526    @Override
527    public boolean areEqual() {
528      return onlyOnLeft.isEmpty() && onlyOnRight.isEmpty() && differences.isEmpty();
529    }
530
531    @Override
532    public Map<K, V> entriesOnlyOnLeft() {
533      return onlyOnLeft;
534    }
535
536    @Override
537    public Map<K, V> entriesOnlyOnRight() {
538      return onlyOnRight;
539    }
540
541    @Override
542    public Map<K, V> entriesInCommon() {
543      return onBoth;
544    }
545
546    @Override
547    public Map<K, ValueDifference<V>> entriesDiffering() {
548      return differences;
549    }
550
551    @Override
552    public boolean equals(Object object) {
553      if (object == this) {
554        return true;
555      }
556      if (object instanceof MapDifference) {
557        MapDifference<?, ?> other = (MapDifference<?, ?>) object;
558        return entriesOnlyOnLeft().equals(other.entriesOnlyOnLeft())
559            && entriesOnlyOnRight().equals(other.entriesOnlyOnRight())
560            && entriesInCommon().equals(other.entriesInCommon())
561            && entriesDiffering().equals(other.entriesDiffering());
562      }
563      return false;
564    }
565
566    @Override
567    public int hashCode() {
568      return Objects.hashCode(
569          entriesOnlyOnLeft(), entriesOnlyOnRight(), entriesInCommon(), entriesDiffering());
570    }
571
572    @Override
573    public String toString() {
574      if (areEqual()) {
575        return "equal";
576      }
577
578      StringBuilder result = new StringBuilder("not equal");
579      if (!onlyOnLeft.isEmpty()) {
580        result.append(": only on left=").append(onlyOnLeft);
581      }
582      if (!onlyOnRight.isEmpty()) {
583        result.append(": only on right=").append(onlyOnRight);
584      }
585      if (!differences.isEmpty()) {
586        result.append(": value differences=").append(differences);
587      }
588      return result.toString();
589    }
590  }
591
592  static class ValueDifferenceImpl<V> implements MapDifference.ValueDifference<V> {
593    @NullableDecl private final V left;
594    @NullableDecl private final V right;
595
596    static <V> ValueDifference<V> create(@NullableDecl V left, @NullableDecl V right) {
597      return new ValueDifferenceImpl<V>(left, right);
598    }
599
600    private ValueDifferenceImpl(@NullableDecl V left, @NullableDecl V right) {
601      this.left = left;
602      this.right = right;
603    }
604
605    @Override
606    public V leftValue() {
607      return left;
608    }
609
610    @Override
611    public V rightValue() {
612      return right;
613    }
614
615    @Override
616    public boolean equals(@NullableDecl Object object) {
617      if (object instanceof MapDifference.ValueDifference) {
618        MapDifference.ValueDifference<?> that = (MapDifference.ValueDifference<?>) object;
619        return Objects.equal(this.left, that.leftValue())
620            && Objects.equal(this.right, that.rightValue());
621      }
622      return false;
623    }
624
625    @Override
626    public int hashCode() {
627      return Objects.hashCode(left, right);
628    }
629
630    @Override
631    public String toString() {
632      return "(" + left + ", " + right + ")";
633    }
634  }
635
636  static class SortedMapDifferenceImpl<K, V> extends MapDifferenceImpl<K, V>
637      implements SortedMapDifference<K, V> {
638    SortedMapDifferenceImpl(
639        SortedMap<K, V> onlyOnLeft,
640        SortedMap<K, V> onlyOnRight,
641        SortedMap<K, V> onBoth,
642        SortedMap<K, ValueDifference<V>> differences) {
643      super(onlyOnLeft, onlyOnRight, onBoth, differences);
644    }
645
646    @Override
647    public SortedMap<K, ValueDifference<V>> entriesDiffering() {
648      return (SortedMap<K, ValueDifference<V>>) super.entriesDiffering();
649    }
650
651    @Override
652    public SortedMap<K, V> entriesInCommon() {
653      return (SortedMap<K, V>) super.entriesInCommon();
654    }
655
656    @Override
657    public SortedMap<K, V> entriesOnlyOnLeft() {
658      return (SortedMap<K, V>) super.entriesOnlyOnLeft();
659    }
660
661    @Override
662    public SortedMap<K, V> entriesOnlyOnRight() {
663      return (SortedMap<K, V>) super.entriesOnlyOnRight();
664    }
665  }
666
667  /**
668   * Returns the specified comparator if not null; otherwise returns {@code Ordering.natural()}.
669   * This method is an abomination of generics; the only purpose of this method is to contain the
670   * ugly type-casting in one place.
671   */
672  @SuppressWarnings("unchecked")
673  static <E> Comparator<? super E> orNaturalOrder(@NullableDecl Comparator<? super E> comparator) {
674    if (comparator != null) { // can't use ? : because of javac bug 5080917
675      return comparator;
676    }
677    return (Comparator<E>) Ordering.natural();
678  }
679
680  /**
681   * Returns a live {@link Map} view whose keys are the contents of {@code set} and whose values are
682   * computed on demand using {@code function}. To get an immutable <i>copy</i> instead, use {@link
683   * #toMap(Iterable, Function)}.
684   *
685   * <p>Specifically, for each {@code k} in the backing set, the returned map has an entry mapping
686   * {@code k} to {@code function.apply(k)}. The {@code keySet}, {@code values}, and {@code
687   * entrySet} views of the returned map iterate in the same order as the backing set.
688   *
689   * <p>Modifications to the backing set are read through to the returned map. The returned map
690   * supports removal operations if the backing set does. Removal operations write through to the
691   * backing set. The returned map does not support put operations.
692   *
693   * <p><b>Warning:</b> If the function rejects {@code null}, caution is required to make sure the
694   * set does not contain {@code null}, because the view cannot stop {@code null} from being added
695   * to the set.
696   *
697   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of key type {@code K},
698   * {@code k.equals(k2)} implies that {@code k2} is also of type {@code K}. Using a key type for
699   * which this may not hold, such as {@code ArrayList}, may risk a {@code ClassCastException} when
700   * calling methods on the resulting map view.
701   *
702   * @since 14.0
703   */
704  public static <K, V> Map<K, V> asMap(Set<K> set, Function<? super K, V> function) {
705    return new AsMapView<>(set, function);
706  }
707
708  /**
709   * Returns a view of the sorted set as a map, mapping keys from the set according to the specified
710   * function.
711   *
712   * <p>Specifically, for each {@code k} in the backing set, the returned map has an entry mapping
713   * {@code k} to {@code function.apply(k)}. The {@code keySet}, {@code values}, and {@code
714   * entrySet} views of the returned map iterate in the same order as the backing set.
715   *
716   * <p>Modifications to the backing set are read through to the returned map. The returned map
717   * supports removal operations if the backing set does. Removal operations write through to the
718   * backing set. The returned map does not support put operations.
719   *
720   * <p><b>Warning:</b> If the function rejects {@code null}, caution is required to make sure the
721   * set does not contain {@code null}, because the view cannot stop {@code null} from being added
722   * to the set.
723   *
724   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of key type {@code K},
725   * {@code k.equals(k2)} implies that {@code k2} is also of type {@code K}. Using a key type for
726   * which this may not hold, such as {@code ArrayList}, may risk a {@code ClassCastException} when
727   * calling methods on the resulting map view.
728   *
729   * @since 14.0
730   */
731  public static <K, V> SortedMap<K, V> asMap(SortedSet<K> set, Function<? super K, V> function) {
732    return new SortedAsMapView<>(set, function);
733  }
734
735  /**
736   * Returns a view of the navigable set as a map, mapping keys from the set according to the
737   * specified function.
738   *
739   * <p>Specifically, for each {@code k} in the backing set, the returned map has an entry mapping
740   * {@code k} to {@code function.apply(k)}. The {@code keySet}, {@code values}, and {@code
741   * entrySet} views of the returned map iterate in the same order as the backing set.
742   *
743   * <p>Modifications to the backing set are read through to the returned map. The returned map
744   * supports removal operations if the backing set does. Removal operations write through to the
745   * backing set. The returned map does not support put operations.
746   *
747   * <p><b>Warning:</b> If the function rejects {@code null}, caution is required to make sure the
748   * set does not contain {@code null}, because the view cannot stop {@code null} from being added
749   * to the set.
750   *
751   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of key type {@code K},
752   * {@code k.equals(k2)} implies that {@code k2} is also of type {@code K}. Using a key type for
753   * which this may not hold, such as {@code ArrayList}, may risk a {@code ClassCastException} when
754   * calling methods on the resulting map view.
755   *
756   * @since 14.0
757   */
758  @GwtIncompatible // NavigableMap
759  public static <K, V> NavigableMap<K, V> asMap(
760      NavigableSet<K> set, Function<? super K, V> function) {
761    return new NavigableAsMapView<>(set, function);
762  }
763
764  private static class AsMapView<K, V> extends ViewCachingAbstractMap<K, V> {
765
766    private final Set<K> set;
767    final Function<? super K, V> function;
768
769    Set<K> backingSet() {
770      return set;
771    }
772
773    AsMapView(Set<K> set, Function<? super K, V> function) {
774      this.set = checkNotNull(set);
775      this.function = checkNotNull(function);
776    }
777
778    @Override
779    public Set<K> createKeySet() {
780      return removeOnlySet(backingSet());
781    }
782
783    @Override
784    Collection<V> createValues() {
785      return Collections2.transform(set, function);
786    }
787
788    @Override
789    public int size() {
790      return backingSet().size();
791    }
792
793    @Override
794    public boolean containsKey(@NullableDecl Object key) {
795      return backingSet().contains(key);
796    }
797
798    @Override
799    public V get(@NullableDecl Object key) {
800      if (Collections2.safeContains(backingSet(), key)) {
801        @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
802        K k = (K) key;
803        return function.apply(k);
804      } else {
805        return null;
806      }
807    }
808
809    @Override
810    public V remove(@NullableDecl Object key) {
811      if (backingSet().remove(key)) {
812        @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
813        K k = (K) key;
814        return function.apply(k);
815      } else {
816        return null;
817      }
818    }
819
820    @Override
821    public void clear() {
822      backingSet().clear();
823    }
824
825    @Override
826    protected Set<Entry<K, V>> createEntrySet() {
827      @WeakOuter
828      class EntrySetImpl extends EntrySet<K, V> {
829        @Override
830        Map<K, V> map() {
831          return AsMapView.this;
832        }
833
834        @Override
835        public Iterator<Entry<K, V>> iterator() {
836          return asMapEntryIterator(backingSet(), function);
837        }
838      }
839      return new EntrySetImpl();
840    }
841  }
842
843  static <K, V> Iterator<Entry<K, V>> asMapEntryIterator(
844      Set<K> set, final Function<? super K, V> function) {
845    return new TransformedIterator<K, Entry<K, V>>(set.iterator()) {
846      @Override
847      Entry<K, V> transform(final K key) {
848        return immutableEntry(key, function.apply(key));
849      }
850    };
851  }
852
853  private static class SortedAsMapView<K, V> extends AsMapView<K, V> implements SortedMap<K, V> {
854
855    SortedAsMapView(SortedSet<K> set, Function<? super K, V> function) {
856      super(set, function);
857    }
858
859    @Override
860    SortedSet<K> backingSet() {
861      return (SortedSet<K>) super.backingSet();
862    }
863
864    @Override
865    public Comparator<? super K> comparator() {
866      return backingSet().comparator();
867    }
868
869    @Override
870    public Set<K> keySet() {
871      return removeOnlySortedSet(backingSet());
872    }
873
874    @Override
875    public SortedMap<K, V> subMap(K fromKey, K toKey) {
876      return asMap(backingSet().subSet(fromKey, toKey), function);
877    }
878
879    @Override
880    public SortedMap<K, V> headMap(K toKey) {
881      return asMap(backingSet().headSet(toKey), function);
882    }
883
884    @Override
885    public SortedMap<K, V> tailMap(K fromKey) {
886      return asMap(backingSet().tailSet(fromKey), function);
887    }
888
889    @Override
890    public K firstKey() {
891      return backingSet().first();
892    }
893
894    @Override
895    public K lastKey() {
896      return backingSet().last();
897    }
898  }
899
900  @GwtIncompatible // NavigableMap
901  private static final class NavigableAsMapView<K, V> extends AbstractNavigableMap<K, V> {
902    /*
903     * Using AbstractNavigableMap is simpler than extending SortedAsMapView and rewriting all the
904     * NavigableMap methods.
905     */
906
907    private final NavigableSet<K> set;
908    private final Function<? super K, V> function;
909
910    NavigableAsMapView(NavigableSet<K> ks, Function<? super K, V> vFunction) {
911      this.set = checkNotNull(ks);
912      this.function = checkNotNull(vFunction);
913    }
914
915    @Override
916    public NavigableMap<K, V> subMap(
917        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
918      return asMap(set.subSet(fromKey, fromInclusive, toKey, toInclusive), function);
919    }
920
921    @Override
922    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
923      return asMap(set.headSet(toKey, inclusive), function);
924    }
925
926    @Override
927    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
928      return asMap(set.tailSet(fromKey, inclusive), function);
929    }
930
931    @Override
932    public Comparator<? super K> comparator() {
933      return set.comparator();
934    }
935
936    @Override
937    @NullableDecl
938    public V get(@NullableDecl Object key) {
939      if (Collections2.safeContains(set, key)) {
940        @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
941        K k = (K) key;
942        return function.apply(k);
943      } else {
944        return null;
945      }
946    }
947
948    @Override
949    public void clear() {
950      set.clear();
951    }
952
953    @Override
954    Iterator<Entry<K, V>> entryIterator() {
955      return asMapEntryIterator(set, function);
956    }
957
958    @Override
959    Iterator<Entry<K, V>> descendingEntryIterator() {
960      return descendingMap().entrySet().iterator();
961    }
962
963    @Override
964    public NavigableSet<K> navigableKeySet() {
965      return removeOnlyNavigableSet(set);
966    }
967
968    @Override
969    public int size() {
970      return set.size();
971    }
972
973    @Override
974    public NavigableMap<K, V> descendingMap() {
975      return asMap(set.descendingSet(), function);
976    }
977  }
978
979  private static <E> Set<E> removeOnlySet(final Set<E> set) {
980    return new ForwardingSet<E>() {
981      @Override
982      protected Set<E> delegate() {
983        return set;
984      }
985
986      @Override
987      public boolean add(E element) {
988        throw new UnsupportedOperationException();
989      }
990
991      @Override
992      public boolean addAll(Collection<? extends E> es) {
993        throw new UnsupportedOperationException();
994      }
995    };
996  }
997
998  private static <E> SortedSet<E> removeOnlySortedSet(final SortedSet<E> set) {
999    return new ForwardingSortedSet<E>() {
1000      @Override
1001      protected SortedSet<E> delegate() {
1002        return set;
1003      }
1004
1005      @Override
1006      public boolean add(E element) {
1007        throw new UnsupportedOperationException();
1008      }
1009
1010      @Override
1011      public boolean addAll(Collection<? extends E> es) {
1012        throw new UnsupportedOperationException();
1013      }
1014
1015      @Override
1016      public SortedSet<E> headSet(E toElement) {
1017        return removeOnlySortedSet(super.headSet(toElement));
1018      }
1019
1020      @Override
1021      public SortedSet<E> subSet(E fromElement, E toElement) {
1022        return removeOnlySortedSet(super.subSet(fromElement, toElement));
1023      }
1024
1025      @Override
1026      public SortedSet<E> tailSet(E fromElement) {
1027        return removeOnlySortedSet(super.tailSet(fromElement));
1028      }
1029    };
1030  }
1031
1032  @GwtIncompatible // NavigableSet
1033  private static <E> NavigableSet<E> removeOnlyNavigableSet(final NavigableSet<E> set) {
1034    return new ForwardingNavigableSet<E>() {
1035      @Override
1036      protected NavigableSet<E> delegate() {
1037        return set;
1038      }
1039
1040      @Override
1041      public boolean add(E element) {
1042        throw new UnsupportedOperationException();
1043      }
1044
1045      @Override
1046      public boolean addAll(Collection<? extends E> es) {
1047        throw new UnsupportedOperationException();
1048      }
1049
1050      @Override
1051      public SortedSet<E> headSet(E toElement) {
1052        return removeOnlySortedSet(super.headSet(toElement));
1053      }
1054
1055      @Override
1056      public NavigableSet<E> headSet(E toElement, boolean inclusive) {
1057        return removeOnlyNavigableSet(super.headSet(toElement, inclusive));
1058      }
1059
1060      @Override
1061      public SortedSet<E> subSet(E fromElement, E toElement) {
1062        return removeOnlySortedSet(super.subSet(fromElement, toElement));
1063      }
1064
1065      @Override
1066      public NavigableSet<E> subSet(
1067          E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
1068        return removeOnlyNavigableSet(
1069            super.subSet(fromElement, fromInclusive, toElement, toInclusive));
1070      }
1071
1072      @Override
1073      public SortedSet<E> tailSet(E fromElement) {
1074        return removeOnlySortedSet(super.tailSet(fromElement));
1075      }
1076
1077      @Override
1078      public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
1079        return removeOnlyNavigableSet(super.tailSet(fromElement, inclusive));
1080      }
1081
1082      @Override
1083      public NavigableSet<E> descendingSet() {
1084        return removeOnlyNavigableSet(super.descendingSet());
1085      }
1086    };
1087  }
1088
1089  /**
1090   * Returns an immutable map whose keys are the distinct elements of {@code keys} and whose value
1091   * for each key was computed by {@code valueFunction}. The map's iteration order is the order of
1092   * the first appearance of each key in {@code keys}.
1093   *
1094   * <p>When there are multiple instances of a key in {@code keys}, it is unspecified whether {@code
1095   * valueFunction} will be applied to more than one instance of that key and, if it is, which
1096   * result will be mapped to that key in the returned map.
1097   *
1098   * <p>If {@code keys} is a {@link Set}, a live view can be obtained instead of a copy using {@link
1099   * Maps#asMap(Set, Function)}.
1100   *
1101   * @throws NullPointerException if any element of {@code keys} is {@code null}, or if {@code
1102   *     valueFunction} produces {@code null} for any key
1103   * @since 14.0
1104   */
1105  public static <K, V> ImmutableMap<K, V> toMap(
1106      Iterable<K> keys, Function<? super K, V> valueFunction) {
1107    return toMap(keys.iterator(), valueFunction);
1108  }
1109
1110  /**
1111   * Returns an immutable map whose keys are the distinct elements of {@code keys} and whose value
1112   * for each key was computed by {@code valueFunction}. The map's iteration order is the order of
1113   * the first appearance of each key in {@code keys}.
1114   *
1115   * <p>When there are multiple instances of a key in {@code keys}, it is unspecified whether {@code
1116   * valueFunction} will be applied to more than one instance of that key and, if it is, which
1117   * result will be mapped to that key in the returned map.
1118   *
1119   * @throws NullPointerException if any element of {@code keys} is {@code null}, or if {@code
1120   *     valueFunction} produces {@code null} for any key
1121   * @since 14.0
1122   */
1123  public static <K, V> ImmutableMap<K, V> toMap(
1124      Iterator<K> keys, Function<? super K, V> valueFunction) {
1125    checkNotNull(valueFunction);
1126    // Using LHM instead of a builder so as not to fail on duplicate keys
1127    Map<K, V> builder = newLinkedHashMap();
1128    while (keys.hasNext()) {
1129      K key = keys.next();
1130      builder.put(key, valueFunction.apply(key));
1131    }
1132    return ImmutableMap.copyOf(builder);
1133  }
1134
1135  /**
1136   * Returns a map with the given {@code values}, indexed by keys derived from those values. In
1137   * other words, each input value produces an entry in the map whose key is the result of applying
1138   * {@code keyFunction} to that value. These entries appear in the same order as the input values.
1139   * Example usage:
1140   *
1141   * <pre>{@code
1142   * Color red = new Color("red", 255, 0, 0);
1143   * ...
1144   * ImmutableSet<Color> allColors = ImmutableSet.of(red, green, blue);
1145   *
1146   * Map<String, Color> colorForName =
1147   *     uniqueIndex(allColors, toStringFunction());
1148   * assertThat(colorForName).containsEntry("red", red);
1149   * }</pre>
1150   *
1151   * <p>If your index may associate multiple values with each key, use {@link
1152   * Multimaps#index(Iterable, Function) Multimaps.index}.
1153   *
1154   * @param values the values to use when constructing the {@code Map}
1155   * @param keyFunction the function used to produce the key for each value
1156   * @return a map mapping the result of evaluating the function {@code keyFunction} on each value
1157   *     in the input collection to that value
1158   * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
1159   *     value in the input collection
1160   * @throws NullPointerException if any element of {@code values} is {@code null}, or if {@code
1161   *     keyFunction} produces {@code null} for any value
1162   */
1163  @CanIgnoreReturnValue
1164  public static <K, V> ImmutableMap<K, V> uniqueIndex(
1165      Iterable<V> values, Function<? super V, K> keyFunction) {
1166    // TODO(lowasser): consider presizing the builder if values is a Collection
1167    return uniqueIndex(values.iterator(), keyFunction);
1168  }
1169
1170  /**
1171   * Returns a map with the given {@code values}, indexed by keys derived from those values. In
1172   * other words, each input value produces an entry in the map whose key is the result of applying
1173   * {@code keyFunction} to that value. These entries appear in the same order as the input values.
1174   * Example usage:
1175   *
1176   * <pre>{@code
1177   * Color red = new Color("red", 255, 0, 0);
1178   * ...
1179   * Iterator<Color> allColors = ImmutableSet.of(red, green, blue).iterator();
1180   *
1181   * Map<String, Color> colorForName =
1182   *     uniqueIndex(allColors, toStringFunction());
1183   * assertThat(colorForName).containsEntry("red", red);
1184   * }</pre>
1185   *
1186   * <p>If your index may associate multiple values with each key, use {@link
1187   * Multimaps#index(Iterator, Function) Multimaps.index}.
1188   *
1189   * @param values the values to use when constructing the {@code Map}
1190   * @param keyFunction the function used to produce the key for each value
1191   * @return a map mapping the result of evaluating the function {@code keyFunction} on each value
1192   *     in the input collection to that value
1193   * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
1194   *     value in the input collection
1195   * @throws NullPointerException if any element of {@code values} is {@code null}, or if {@code
1196   *     keyFunction} produces {@code null} for any value
1197   * @since 10.0
1198   */
1199  @CanIgnoreReturnValue
1200  public static <K, V> ImmutableMap<K, V> uniqueIndex(
1201      Iterator<V> values, Function<? super V, K> keyFunction) {
1202    checkNotNull(keyFunction);
1203    ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
1204    while (values.hasNext()) {
1205      V value = values.next();
1206      builder.put(keyFunction.apply(value), value);
1207    }
1208    try {
1209      return builder.build();
1210    } catch (IllegalArgumentException duplicateKeys) {
1211      throw new IllegalArgumentException(
1212          duplicateKeys.getMessage()
1213              + ". To index multiple values under a key, use Multimaps.index.");
1214    }
1215  }
1216
1217  /**
1218   * Creates an {@code ImmutableMap<String, String>} from a {@code Properties} instance. Properties
1219   * normally derive from {@code Map<Object, Object>}, but they typically contain strings, which is
1220   * awkward. This method lets you get a plain-old-{@code Map} out of a {@code Properties}.
1221   *
1222   * @param properties a {@code Properties} object to be converted
1223   * @return an immutable map containing all the entries in {@code properties}
1224   * @throws ClassCastException if any key in {@code Properties} is not a {@code String}
1225   * @throws NullPointerException if any key or value in {@code Properties} is null
1226   */
1227  @GwtIncompatible // java.util.Properties
1228  public static ImmutableMap<String, String> fromProperties(Properties properties) {
1229    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
1230
1231    for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements(); ) {
1232      String key = (String) e.nextElement();
1233      builder.put(key, properties.getProperty(key));
1234    }
1235
1236    return builder.build();
1237  }
1238
1239  /**
1240   * Returns an immutable map entry with the specified key and value. The {@link Entry#setValue}
1241   * operation throws an {@link UnsupportedOperationException}.
1242   *
1243   * <p>The returned entry is serializable.
1244   *
1245   * <p><b>Java 9 users:</b> consider using {@code java.util.Map.entry(key, value)} if the key and
1246   * value are non-null and the entry does not need to be serializable.
1247   *
1248   * @param key the key to be associated with the returned entry
1249   * @param value the value to be associated with the returned entry
1250   */
1251  @GwtCompatible(serializable = true)
1252  public static <K, V> Entry<K, V> immutableEntry(@NullableDecl K key, @NullableDecl V value) {
1253    return new ImmutableEntry<>(key, value);
1254  }
1255
1256  /**
1257   * Returns an unmodifiable view of the specified set of entries. The {@link Entry#setValue}
1258   * operation throws an {@link UnsupportedOperationException}, as do any operations that would
1259   * modify the returned set.
1260   *
1261   * @param entrySet the entries for which to return an unmodifiable view
1262   * @return an unmodifiable view of the entries
1263   */
1264  static <K, V> Set<Entry<K, V>> unmodifiableEntrySet(Set<Entry<K, V>> entrySet) {
1265    return new UnmodifiableEntrySet<>(Collections.unmodifiableSet(entrySet));
1266  }
1267
1268  /**
1269   * Returns an unmodifiable view of the specified map entry. The {@link Entry#setValue} operation
1270   * throws an {@link UnsupportedOperationException}. This also has the side-effect of redefining
1271   * {@code equals} to comply with the Entry contract, to avoid a possible nefarious implementation
1272   * of equals.
1273   *
1274   * @param entry the entry for which to return an unmodifiable view
1275   * @return an unmodifiable view of the entry
1276   */
1277  static <K, V> Entry<K, V> unmodifiableEntry(final Entry<? extends K, ? extends V> entry) {
1278    checkNotNull(entry);
1279    return new AbstractMapEntry<K, V>() {
1280      @Override
1281      public K getKey() {
1282        return entry.getKey();
1283      }
1284
1285      @Override
1286      public V getValue() {
1287        return entry.getValue();
1288      }
1289    };
1290  }
1291
1292  static <K, V> UnmodifiableIterator<Entry<K, V>> unmodifiableEntryIterator(
1293      final Iterator<Entry<K, V>> entryIterator) {
1294    return new UnmodifiableIterator<Entry<K, V>>() {
1295      @Override
1296      public boolean hasNext() {
1297        return entryIterator.hasNext();
1298      }
1299
1300      @Override
1301      public Entry<K, V> next() {
1302        return unmodifiableEntry(entryIterator.next());
1303      }
1304    };
1305  }
1306
1307  /** @see Multimaps#unmodifiableEntries */
1308  static class UnmodifiableEntries<K, V> extends ForwardingCollection<Entry<K, V>> {
1309    private final Collection<Entry<K, V>> entries;
1310
1311    UnmodifiableEntries(Collection<Entry<K, V>> entries) {
1312      this.entries = entries;
1313    }
1314
1315    @Override
1316    protected Collection<Entry<K, V>> delegate() {
1317      return entries;
1318    }
1319
1320    @Override
1321    public Iterator<Entry<K, V>> iterator() {
1322      return unmodifiableEntryIterator(entries.iterator());
1323    }
1324
1325    // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
1326
1327    @Override
1328    public Object[] toArray() {
1329      return standardToArray();
1330    }
1331
1332    @Override
1333    public <T> T[] toArray(T[] array) {
1334      return standardToArray(array);
1335    }
1336  }
1337
1338  /** @see Maps#unmodifiableEntrySet(Set) */
1339  static class UnmodifiableEntrySet<K, V> extends UnmodifiableEntries<K, V>
1340      implements Set<Entry<K, V>> {
1341    UnmodifiableEntrySet(Set<Entry<K, V>> entries) {
1342      super(entries);
1343    }
1344
1345    // See java.util.Collections.UnmodifiableEntrySet for details on attacks.
1346
1347    @Override
1348    public boolean equals(@NullableDecl Object object) {
1349      return Sets.equalsImpl(this, object);
1350    }
1351
1352    @Override
1353    public int hashCode() {
1354      return Sets.hashCodeImpl(this);
1355    }
1356  }
1357
1358  /**
1359   * Returns a {@link Converter} that converts values using {@link BiMap#get bimap.get()}, and whose
1360   * inverse view converts values using {@link BiMap#inverse bimap.inverse()}{@code .get()}.
1361   *
1362   * <p>To use a plain {@link Map} as a {@link Function}, see {@link
1363   * com.google.common.base.Functions#forMap(Map)} or {@link
1364   * com.google.common.base.Functions#forMap(Map, Object)}.
1365   *
1366   * @since 16.0
1367   */
1368  public static <A, B> Converter<A, B> asConverter(final BiMap<A, B> bimap) {
1369    return new BiMapConverter<>(bimap);
1370  }
1371
1372  private static final class BiMapConverter<A, B> extends Converter<A, B> implements Serializable {
1373    private final BiMap<A, B> bimap;
1374
1375    BiMapConverter(BiMap<A, B> bimap) {
1376      this.bimap = checkNotNull(bimap);
1377    }
1378
1379    @Override
1380    protected B doForward(A a) {
1381      return convert(bimap, a);
1382    }
1383
1384    @Override
1385    protected A doBackward(B b) {
1386      return convert(bimap.inverse(), b);
1387    }
1388
1389    private static <X, Y> Y convert(BiMap<X, Y> bimap, X input) {
1390      Y output = bimap.get(input);
1391      checkArgument(output != null, "No non-null mapping present for input: %s", input);
1392      return output;
1393    }
1394
1395    @Override
1396    public boolean equals(@NullableDecl Object object) {
1397      if (object instanceof BiMapConverter) {
1398        BiMapConverter<?, ?> that = (BiMapConverter<?, ?>) object;
1399        return this.bimap.equals(that.bimap);
1400      }
1401      return false;
1402    }
1403
1404    @Override
1405    public int hashCode() {
1406      return bimap.hashCode();
1407    }
1408
1409    // There's really no good way to implement toString() without printing the entire BiMap, right?
1410    @Override
1411    public String toString() {
1412      return "Maps.asConverter(" + bimap + ")";
1413    }
1414
1415    private static final long serialVersionUID = 0L;
1416  }
1417
1418  /**
1419   * Returns a synchronized (thread-safe) bimap backed by the specified bimap. In order to guarantee
1420   * serial access, it is critical that <b>all</b> access to the backing bimap is accomplished
1421   * through the returned bimap.
1422   *
1423   * <p>It is imperative that the user manually synchronize on the returned map when accessing any
1424   * of its collection views:
1425   *
1426   * <pre>{@code
1427   * BiMap<Long, String> map = Maps.synchronizedBiMap(
1428   *     HashBiMap.<Long, String>create());
1429   * ...
1430   * Set<Long> set = map.keySet();  // Needn't be in synchronized block
1431   * ...
1432   * synchronized (map) {  // Synchronizing on map, not set!
1433   *   Iterator<Long> it = set.iterator(); // Must be in synchronized block
1434   *   while (it.hasNext()) {
1435   *     foo(it.next());
1436   *   }
1437   * }
1438   * }</pre>
1439   *
1440   * <p>Failure to follow this advice may result in non-deterministic behavior.
1441   *
1442   * <p>The returned bimap will be serializable if the specified bimap is serializable.
1443   *
1444   * @param bimap the bimap to be wrapped in a synchronized view
1445   * @return a synchronized view of the specified bimap
1446   */
1447  public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
1448    return Synchronized.biMap(bimap, null);
1449  }
1450
1451  /**
1452   * Returns an unmodifiable view of the specified bimap. This method allows modules to provide
1453   * users with "read-only" access to internal bimaps. Query operations on the returned bimap "read
1454   * through" to the specified bimap, and attempts to modify the returned map, whether direct or via
1455   * its collection views, result in an {@code UnsupportedOperationException}.
1456   *
1457   * <p>The returned bimap will be serializable if the specified bimap is serializable.
1458   *
1459   * @param bimap the bimap for which an unmodifiable view is to be returned
1460   * @return an unmodifiable view of the specified bimap
1461   */
1462  public static <K, V> BiMap<K, V> unmodifiableBiMap(BiMap<? extends K, ? extends V> bimap) {
1463    return new UnmodifiableBiMap<>(bimap, null);
1464  }
1465
1466  /** @see Maps#unmodifiableBiMap(BiMap) */
1467  private static class UnmodifiableBiMap<K, V> extends ForwardingMap<K, V>
1468      implements BiMap<K, V>, Serializable {
1469    final Map<K, V> unmodifiableMap;
1470    final BiMap<? extends K, ? extends V> delegate;
1471    @MonotonicNonNullDecl @RetainedWith BiMap<V, K> inverse;
1472    @MonotonicNonNullDecl transient Set<V> values;
1473
1474    UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate, @NullableDecl BiMap<V, K> inverse) {
1475      unmodifiableMap = Collections.unmodifiableMap(delegate);
1476      this.delegate = delegate;
1477      this.inverse = inverse;
1478    }
1479
1480    @Override
1481    protected Map<K, V> delegate() {
1482      return unmodifiableMap;
1483    }
1484
1485    @Override
1486    public V forcePut(K key, V value) {
1487      throw new UnsupportedOperationException();
1488    }
1489
1490    @Override
1491    public BiMap<V, K> inverse() {
1492      BiMap<V, K> result = inverse;
1493      return (result == null)
1494          ? inverse = new UnmodifiableBiMap<>(delegate.inverse(), this)
1495          : result;
1496    }
1497
1498    @Override
1499    public Set<V> values() {
1500      Set<V> result = values;
1501      return (result == null) ? values = Collections.unmodifiableSet(delegate.values()) : result;
1502    }
1503
1504    private static final long serialVersionUID = 0;
1505  }
1506
1507  /**
1508   * Returns a view of a map where each value is transformed by a function. All other properties of
1509   * the map, such as iteration order, are left intact. For example, the code:
1510   *
1511   * <pre>{@code
1512   * Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
1513   * Function<Integer, Double> sqrt =
1514   *     new Function<Integer, Double>() {
1515   *       public Double apply(Integer in) {
1516   *         return Math.sqrt((int) in);
1517   *       }
1518   *     };
1519   * Map<String, Double> transformed = Maps.transformValues(map, sqrt);
1520   * System.out.println(transformed);
1521   * }</pre>
1522   *
1523   * ... prints {@code {a=2.0, b=3.0}}.
1524   *
1525   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1526   * removal operations, and these are reflected in the underlying map.
1527   *
1528   * <p>It's acceptable for the underlying map to contain null keys, and even null values provided
1529   * that the function is capable of accepting null input. The transformed map might contain null
1530   * values, if the function sometimes gives a null result.
1531   *
1532   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1533   *
1534   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned map
1535   * to be a view, but it means that the function will be applied many times for bulk operations
1536   * like {@link Map#containsValue} and {@code Map.toString()}. For this to perform well, {@code
1537   * function} should be fast. To avoid lazy evaluation when the returned map doesn't need to be a
1538   * view, copy the returned map into a new map of your choosing.
1539   */
1540  public static <K, V1, V2> Map<K, V2> transformValues(
1541      Map<K, V1> fromMap, Function<? super V1, V2> function) {
1542    return transformEntries(fromMap, asEntryTransformer(function));
1543  }
1544
1545  /**
1546   * Returns a view of a sorted map where each value is transformed by a function. All other
1547   * properties of the map, such as iteration order, are left intact. For example, the code:
1548   *
1549   * <pre>{@code
1550   * SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
1551   * Function<Integer, Double> sqrt =
1552   *     new Function<Integer, Double>() {
1553   *       public Double apply(Integer in) {
1554   *         return Math.sqrt((int) in);
1555   *       }
1556   *     };
1557   * SortedMap<String, Double> transformed =
1558   *      Maps.transformValues(map, sqrt);
1559   * System.out.println(transformed);
1560   * }</pre>
1561   *
1562   * ... prints {@code {a=2.0, b=3.0}}.
1563   *
1564   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1565   * removal operations, and these are reflected in the underlying map.
1566   *
1567   * <p>It's acceptable for the underlying map to contain null keys, and even null values provided
1568   * that the function is capable of accepting null input. The transformed map might contain null
1569   * values, if the function sometimes gives a null result.
1570   *
1571   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1572   *
1573   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned map
1574   * to be a view, but it means that the function will be applied many times for bulk operations
1575   * like {@link Map#containsValue} and {@code Map.toString()}. For this to perform well, {@code
1576   * function} should be fast. To avoid lazy evaluation when the returned map doesn't need to be a
1577   * view, copy the returned map into a new map of your choosing.
1578   *
1579   * @since 11.0
1580   */
1581  public static <K, V1, V2> SortedMap<K, V2> transformValues(
1582      SortedMap<K, V1> fromMap, Function<? super V1, V2> function) {
1583    return transformEntries(fromMap, asEntryTransformer(function));
1584  }
1585
1586  /**
1587   * Returns a view of a navigable map where each value is transformed by a function. All other
1588   * properties of the map, such as iteration order, are left intact. For example, the code:
1589   *
1590   * <pre>{@code
1591   * NavigableMap<String, Integer> map = Maps.newTreeMap();
1592   * map.put("a", 4);
1593   * map.put("b", 9);
1594   * Function<Integer, Double> sqrt =
1595   *     new Function<Integer, Double>() {
1596   *       public Double apply(Integer in) {
1597   *         return Math.sqrt((int) in);
1598   *       }
1599   *     };
1600   * NavigableMap<String, Double> transformed =
1601   *      Maps.transformNavigableValues(map, sqrt);
1602   * System.out.println(transformed);
1603   * }</pre>
1604   *
1605   * ... prints {@code {a=2.0, b=3.0}}.
1606   *
1607   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1608   * removal operations, and these are reflected in the underlying map.
1609   *
1610   * <p>It's acceptable for the underlying map to contain null keys, and even null values provided
1611   * that the function is capable of accepting null input. The transformed map might contain null
1612   * values, if the function sometimes gives a null result.
1613   *
1614   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1615   *
1616   * <p>The function is applied lazily, invoked when needed. This is necessary for the returned map
1617   * to be a view, but it means that the function will be applied many times for bulk operations
1618   * like {@link Map#containsValue} and {@code Map.toString()}. For this to perform well, {@code
1619   * function} should be fast. To avoid lazy evaluation when the returned map doesn't need to be a
1620   * view, copy the returned map into a new map of your choosing.
1621   *
1622   * @since 13.0
1623   */
1624  @GwtIncompatible // NavigableMap
1625  public static <K, V1, V2> NavigableMap<K, V2> transformValues(
1626      NavigableMap<K, V1> fromMap, Function<? super V1, V2> function) {
1627    return transformEntries(fromMap, asEntryTransformer(function));
1628  }
1629
1630  /**
1631   * Returns a view of a map whose values are derived from the original map's entries. In contrast
1632   * to {@link #transformValues}, this method's entry-transformation logic may depend on the key as
1633   * well as the value.
1634   *
1635   * <p>All other properties of the transformed map, such as iteration order, are left intact. For
1636   * example, the code:
1637   *
1638   * <pre>{@code
1639   * Map<String, Boolean> options =
1640   *     ImmutableMap.of("verbose", true, "sort", false);
1641   * EntryTransformer<String, Boolean, String> flagPrefixer =
1642   *     new EntryTransformer<String, Boolean, String>() {
1643   *       public String transformEntry(String key, Boolean value) {
1644   *         return value ? key : "no" + key;
1645   *       }
1646   *     };
1647   * Map<String, String> transformed =
1648   *     Maps.transformEntries(options, flagPrefixer);
1649   * System.out.println(transformed);
1650   * }</pre>
1651   *
1652   * ... prints {@code {verbose=verbose, sort=nosort}}.
1653   *
1654   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1655   * removal operations, and these are reflected in the underlying map.
1656   *
1657   * <p>It's acceptable for the underlying map to contain null keys and null values provided that
1658   * the transformer is capable of accepting null inputs. The transformed map might contain null
1659   * values if the transformer sometimes gives a null result.
1660   *
1661   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1662   *
1663   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1664   * map to be a view, but it means that the transformer will be applied many times for bulk
1665   * operations like {@link Map#containsValue} and {@link Object#toString}. For this to perform
1666   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned map
1667   * doesn't need to be a view, copy the returned map into a new map of your choosing.
1668   *
1669   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1670   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1671   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1672   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1673   * transformed map.
1674   *
1675   * @since 7.0
1676   */
1677  public static <K, V1, V2> Map<K, V2> transformEntries(
1678      Map<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1679    return new TransformedEntriesMap<>(fromMap, transformer);
1680  }
1681
1682  /**
1683   * Returns a view of a sorted map whose values are derived from the original sorted map's entries.
1684   * In contrast to {@link #transformValues}, this method's entry-transformation logic may depend on
1685   * the key as well as the value.
1686   *
1687   * <p>All other properties of the transformed map, such as iteration order, are left intact. For
1688   * example, the code:
1689   *
1690   * <pre>{@code
1691   * Map<String, Boolean> options =
1692   *     ImmutableSortedMap.of("verbose", true, "sort", false);
1693   * EntryTransformer<String, Boolean, String> flagPrefixer =
1694   *     new EntryTransformer<String, Boolean, String>() {
1695   *       public String transformEntry(String key, Boolean value) {
1696   *         return value ? key : "yes" + key;
1697   *       }
1698   *     };
1699   * SortedMap<String, String> transformed =
1700   *     Maps.transformEntries(options, flagPrefixer);
1701   * System.out.println(transformed);
1702   * }</pre>
1703   *
1704   * ... prints {@code {sort=yessort, verbose=verbose}}.
1705   *
1706   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1707   * removal operations, and these are reflected in the underlying map.
1708   *
1709   * <p>It's acceptable for the underlying map to contain null keys and null values provided that
1710   * the transformer is capable of accepting null inputs. The transformed map might contain null
1711   * values if the transformer sometimes gives a null result.
1712   *
1713   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1714   *
1715   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1716   * map to be a view, but it means that the transformer will be applied many times for bulk
1717   * operations like {@link Map#containsValue} and {@link Object#toString}. For this to perform
1718   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned map
1719   * doesn't need to be a view, copy the returned map into a new map of your choosing.
1720   *
1721   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1722   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1723   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1724   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1725   * transformed map.
1726   *
1727   * @since 11.0
1728   */
1729  public static <K, V1, V2> SortedMap<K, V2> transformEntries(
1730      SortedMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1731    return new TransformedEntriesSortedMap<>(fromMap, transformer);
1732  }
1733
1734  /**
1735   * Returns a view of a navigable map whose values are derived from the original navigable map's
1736   * entries. In contrast to {@link #transformValues}, this method's entry-transformation logic may
1737   * depend on the key as well as the value.
1738   *
1739   * <p>All other properties of the transformed map, such as iteration order, are left intact. For
1740   * example, the code:
1741   *
1742   * <pre>{@code
1743   * NavigableMap<String, Boolean> options = Maps.newTreeMap();
1744   * options.put("verbose", false);
1745   * options.put("sort", true);
1746   * EntryTransformer<String, Boolean, String> flagPrefixer =
1747   *     new EntryTransformer<String, Boolean, String>() {
1748   *       public String transformEntry(String key, Boolean value) {
1749   *         return value ? key : ("yes" + key);
1750   *       }
1751   *     };
1752   * NavigableMap<String, String> transformed =
1753   *     LabsMaps.transformNavigableEntries(options, flagPrefixer);
1754   * System.out.println(transformed);
1755   * }</pre>
1756   *
1757   * ... prints {@code {sort=yessort, verbose=verbose}}.
1758   *
1759   * <p>Changes in the underlying map are reflected in this view. Conversely, this view supports
1760   * removal operations, and these are reflected in the underlying map.
1761   *
1762   * <p>It's acceptable for the underlying map to contain null keys and null values provided that
1763   * the transformer is capable of accepting null inputs. The transformed map might contain null
1764   * values if the transformer sometimes gives a null result.
1765   *
1766   * <p>The returned map is not thread-safe or serializable, even if the underlying map is.
1767   *
1768   * <p>The transformer is applied lazily, invoked when needed. This is necessary for the returned
1769   * map to be a view, but it means that the transformer will be applied many times for bulk
1770   * operations like {@link Map#containsValue} and {@link Object#toString}. For this to perform
1771   * well, {@code transformer} should be fast. To avoid lazy evaluation when the returned map
1772   * doesn't need to be a view, copy the returned map into a new map of your choosing.
1773   *
1774   * <p><b>Warning:</b> This method assumes that for any instance {@code k} of {@code
1775   * EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
1776   * type {@code K}. Using an {@code EntryTransformer} key type for which this may not hold, such as
1777   * {@code ArrayList}, may risk a {@code ClassCastException} when calling methods on the
1778   * transformed map.
1779   *
1780   * @since 13.0
1781   */
1782  @GwtIncompatible // NavigableMap
1783  public static <K, V1, V2> NavigableMap<K, V2> transformEntries(
1784      NavigableMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1785    return new TransformedEntriesNavigableMap<>(fromMap, transformer);
1786  }
1787
1788  /**
1789   * A transformation of the value of a key-value pair, using both key and value as inputs. To apply
1790   * the transformation to a map, use {@link Maps#transformEntries(Map, EntryTransformer)}.
1791   *
1792   * @param <K> the key type of the input and output entries
1793   * @param <V1> the value type of the input entry
1794   * @param <V2> the value type of the output entry
1795   * @since 7.0
1796   */
1797  public interface EntryTransformer<K, V1, V2> {
1798    /**
1799     * Determines an output value based on a key-value pair. This method is <i>generally
1800     * expected</i>, but not absolutely required, to have the following properties:
1801     *
1802     * <ul>
1803     *   <li>Its execution does not cause any observable side effects.
1804     *   <li>The computation is <i>consistent with equals</i>; that is, {@link Objects#equal
1805     *       Objects.equal}{@code (k1, k2) &&} {@link Objects#equal}{@code (v1, v2)} implies that
1806     *       {@code Objects.equal(transformer.transform(k1, v1), transformer.transform(k2, v2))}.
1807     * </ul>
1808     *
1809     * @throws NullPointerException if the key or value is null and this transformer does not accept
1810     *     null arguments
1811     */
1812    V2 transformEntry(@NullableDecl K key, @NullableDecl V1 value);
1813  }
1814
1815  /** Views a function as an entry transformer that ignores the entry key. */
1816  static <K, V1, V2> EntryTransformer<K, V1, V2> asEntryTransformer(
1817      final Function<? super V1, V2> function) {
1818    checkNotNull(function);
1819    return new EntryTransformer<K, V1, V2>() {
1820      @Override
1821      public V2 transformEntry(K key, V1 value) {
1822        return function.apply(value);
1823      }
1824    };
1825  }
1826
1827  static <K, V1, V2> Function<V1, V2> asValueToValueFunction(
1828      final EntryTransformer<? super K, V1, V2> transformer, final K key) {
1829    checkNotNull(transformer);
1830    return new Function<V1, V2>() {
1831      @Override
1832      public V2 apply(@NullableDecl V1 v1) {
1833        return transformer.transformEntry(key, v1);
1834      }
1835    };
1836  }
1837
1838  /** Views an entry transformer as a function from {@code Entry} to values. */
1839  static <K, V1, V2> Function<Entry<K, V1>, V2> asEntryToValueFunction(
1840      final EntryTransformer<? super K, ? super V1, V2> transformer) {
1841    checkNotNull(transformer);
1842    return new Function<Entry<K, V1>, V2>() {
1843      @Override
1844      public V2 apply(Entry<K, V1> entry) {
1845        return transformer.transformEntry(entry.getKey(), entry.getValue());
1846      }
1847    };
1848  }
1849
1850  /** Returns a view of an entry transformed by the specified transformer. */
1851  static <V2, K, V1> Entry<K, V2> transformEntry(
1852      final EntryTransformer<? super K, ? super V1, V2> transformer, final Entry<K, V1> entry) {
1853    checkNotNull(transformer);
1854    checkNotNull(entry);
1855    return new AbstractMapEntry<K, V2>() {
1856      @Override
1857      public K getKey() {
1858        return entry.getKey();
1859      }
1860
1861      @Override
1862      public V2 getValue() {
1863        return transformer.transformEntry(entry.getKey(), entry.getValue());
1864      }
1865    };
1866  }
1867
1868  /** Views an entry transformer as a function from entries to entries. */
1869  static <K, V1, V2> Function<Entry<K, V1>, Entry<K, V2>> asEntryToEntryFunction(
1870      final EntryTransformer<? super K, ? super V1, V2> transformer) {
1871    checkNotNull(transformer);
1872    return new Function<Entry<K, V1>, Entry<K, V2>>() {
1873      @Override
1874      public Entry<K, V2> apply(final Entry<K, V1> entry) {
1875        return transformEntry(transformer, entry);
1876      }
1877    };
1878  }
1879
1880  static class TransformedEntriesMap<K, V1, V2> extends IteratorBasedAbstractMap<K, V2> {
1881    final Map<K, V1> fromMap;
1882    final EntryTransformer<? super K, ? super V1, V2> transformer;
1883
1884    TransformedEntriesMap(
1885        Map<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1886      this.fromMap = checkNotNull(fromMap);
1887      this.transformer = checkNotNull(transformer);
1888    }
1889
1890    @Override
1891    public int size() {
1892      return fromMap.size();
1893    }
1894
1895    @Override
1896    public boolean containsKey(Object key) {
1897      return fromMap.containsKey(key);
1898    }
1899
1900    // safe as long as the user followed the <b>Warning</b> in the javadoc
1901    @SuppressWarnings("unchecked")
1902    @Override
1903    public V2 get(Object key) {
1904      V1 value = fromMap.get(key);
1905      return (value != null || fromMap.containsKey(key))
1906          ? transformer.transformEntry((K) key, value)
1907          : null;
1908    }
1909
1910    // safe as long as the user followed the <b>Warning</b> in the javadoc
1911    @SuppressWarnings("unchecked")
1912    @Override
1913    public V2 remove(Object key) {
1914      return fromMap.containsKey(key)
1915          ? transformer.transformEntry((K) key, fromMap.remove(key))
1916          : null;
1917    }
1918
1919    @Override
1920    public void clear() {
1921      fromMap.clear();
1922    }
1923
1924    @Override
1925    public Set<K> keySet() {
1926      return fromMap.keySet();
1927    }
1928
1929    @Override
1930    Iterator<Entry<K, V2>> entryIterator() {
1931      return Iterators.transform(
1932          fromMap.entrySet().iterator(), Maps.<K, V1, V2>asEntryToEntryFunction(transformer));
1933    }
1934
1935    @Override
1936    public Collection<V2> values() {
1937      return new Values<>(this);
1938    }
1939  }
1940
1941  static class TransformedEntriesSortedMap<K, V1, V2> extends TransformedEntriesMap<K, V1, V2>
1942      implements SortedMap<K, V2> {
1943
1944    protected SortedMap<K, V1> fromMap() {
1945      return (SortedMap<K, V1>) fromMap;
1946    }
1947
1948    TransformedEntriesSortedMap(
1949        SortedMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1950      super(fromMap, transformer);
1951    }
1952
1953    @Override
1954    public Comparator<? super K> comparator() {
1955      return fromMap().comparator();
1956    }
1957
1958    @Override
1959    public K firstKey() {
1960      return fromMap().firstKey();
1961    }
1962
1963    @Override
1964    public SortedMap<K, V2> headMap(K toKey) {
1965      return transformEntries(fromMap().headMap(toKey), transformer);
1966    }
1967
1968    @Override
1969    public K lastKey() {
1970      return fromMap().lastKey();
1971    }
1972
1973    @Override
1974    public SortedMap<K, V2> subMap(K fromKey, K toKey) {
1975      return transformEntries(fromMap().subMap(fromKey, toKey), transformer);
1976    }
1977
1978    @Override
1979    public SortedMap<K, V2> tailMap(K fromKey) {
1980      return transformEntries(fromMap().tailMap(fromKey), transformer);
1981    }
1982  }
1983
1984  @GwtIncompatible // NavigableMap
1985  private static class TransformedEntriesNavigableMap<K, V1, V2>
1986      extends TransformedEntriesSortedMap<K, V1, V2> implements NavigableMap<K, V2> {
1987
1988    TransformedEntriesNavigableMap(
1989        NavigableMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer) {
1990      super(fromMap, transformer);
1991    }
1992
1993    @Override
1994    public Entry<K, V2> ceilingEntry(K key) {
1995      return transformEntry(fromMap().ceilingEntry(key));
1996    }
1997
1998    @Override
1999    public K ceilingKey(K key) {
2000      return fromMap().ceilingKey(key);
2001    }
2002
2003    @Override
2004    public NavigableSet<K> descendingKeySet() {
2005      return fromMap().descendingKeySet();
2006    }
2007
2008    @Override
2009    public NavigableMap<K, V2> descendingMap() {
2010      return transformEntries(fromMap().descendingMap(), transformer);
2011    }
2012
2013    @Override
2014    public Entry<K, V2> firstEntry() {
2015      return transformEntry(fromMap().firstEntry());
2016    }
2017
2018    @Override
2019    public Entry<K, V2> floorEntry(K key) {
2020      return transformEntry(fromMap().floorEntry(key));
2021    }
2022
2023    @Override
2024    public K floorKey(K key) {
2025      return fromMap().floorKey(key);
2026    }
2027
2028    @Override
2029    public NavigableMap<K, V2> headMap(K toKey) {
2030      return headMap(toKey, false);
2031    }
2032
2033    @Override
2034    public NavigableMap<K, V2> headMap(K toKey, boolean inclusive) {
2035      return transformEntries(fromMap().headMap(toKey, inclusive), transformer);
2036    }
2037
2038    @Override
2039    public Entry<K, V2> higherEntry(K key) {
2040      return transformEntry(fromMap().higherEntry(key));
2041    }
2042
2043    @Override
2044    public K higherKey(K key) {
2045      return fromMap().higherKey(key);
2046    }
2047
2048    @Override
2049    public Entry<K, V2> lastEntry() {
2050      return transformEntry(fromMap().lastEntry());
2051    }
2052
2053    @Override
2054    public Entry<K, V2> lowerEntry(K key) {
2055      return transformEntry(fromMap().lowerEntry(key));
2056    }
2057
2058    @Override
2059    public K lowerKey(K key) {
2060      return fromMap().lowerKey(key);
2061    }
2062
2063    @Override
2064    public NavigableSet<K> navigableKeySet() {
2065      return fromMap().navigableKeySet();
2066    }
2067
2068    @Override
2069    public Entry<K, V2> pollFirstEntry() {
2070      return transformEntry(fromMap().pollFirstEntry());
2071    }
2072
2073    @Override
2074    public Entry<K, V2> pollLastEntry() {
2075      return transformEntry(fromMap().pollLastEntry());
2076    }
2077
2078    @Override
2079    public NavigableMap<K, V2> subMap(
2080        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
2081      return transformEntries(
2082          fromMap().subMap(fromKey, fromInclusive, toKey, toInclusive), transformer);
2083    }
2084
2085    @Override
2086    public NavigableMap<K, V2> subMap(K fromKey, K toKey) {
2087      return subMap(fromKey, true, toKey, false);
2088    }
2089
2090    @Override
2091    public NavigableMap<K, V2> tailMap(K fromKey) {
2092      return tailMap(fromKey, true);
2093    }
2094
2095    @Override
2096    public NavigableMap<K, V2> tailMap(K fromKey, boolean inclusive) {
2097      return transformEntries(fromMap().tailMap(fromKey, inclusive), transformer);
2098    }
2099
2100    @NullableDecl
2101    private Entry<K, V2> transformEntry(@NullableDecl Entry<K, V1> entry) {
2102      return (entry == null) ? null : Maps.transformEntry(transformer, entry);
2103    }
2104
2105    @Override
2106    protected NavigableMap<K, V1> fromMap() {
2107      return (NavigableMap<K, V1>) super.fromMap();
2108    }
2109  }
2110
2111  static <K> Predicate<Entry<K, ?>> keyPredicateOnEntries(Predicate<? super K> keyPredicate) {
2112    return compose(keyPredicate, Maps.<K>keyFunction());
2113  }
2114
2115  static <V> Predicate<Entry<?, V>> valuePredicateOnEntries(Predicate<? super V> valuePredicate) {
2116    return compose(valuePredicate, Maps.<V>valueFunction());
2117  }
2118
2119  /**
2120   * Returns a map containing the mappings in {@code unfiltered} whose keys satisfy a predicate. The
2121   * returned map is a live view of {@code unfiltered}; changes to one affect the other.
2122   *
2123   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2124   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2125   * and its views. When given a key that doesn't satisfy the predicate, the map's {@code put()} and
2126   * {@code putAll()} methods throw an {@link IllegalArgumentException}.
2127   *
2128   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2129   * or its views, only mappings whose keys satisfy the filter will be removed from the underlying
2130   * map.
2131   *
2132   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2133   *
2134   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2135   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2136   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2137   *
2138   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
2139   * {@link Predicate#apply}. Do not provide a predicate such as {@code
2140   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2141   */
2142  public static <K, V> Map<K, V> filterKeys(
2143      Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2144    checkNotNull(keyPredicate);
2145    Predicate<Entry<K, ?>> entryPredicate = keyPredicateOnEntries(keyPredicate);
2146    return (unfiltered instanceof AbstractFilteredMap)
2147        ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
2148        : new FilteredKeyMap<K, V>(checkNotNull(unfiltered), keyPredicate, entryPredicate);
2149  }
2150
2151  /**
2152   * Returns a sorted map containing the mappings in {@code unfiltered} whose keys satisfy a
2153   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2154   * other.
2155   *
2156   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2157   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2158   * and its views. When given a key that doesn't satisfy the predicate, the map's {@code put()} and
2159   * {@code putAll()} methods throw an {@link IllegalArgumentException}.
2160   *
2161   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2162   * or its views, only mappings whose keys satisfy the filter will be removed from the underlying
2163   * map.
2164   *
2165   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2166   *
2167   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2168   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2169   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2170   *
2171   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
2172   * {@link Predicate#apply}. Do not provide a predicate such as {@code
2173   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2174   *
2175   * @since 11.0
2176   */
2177  public static <K, V> SortedMap<K, V> filterKeys(
2178      SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2179    // TODO(lowasser): Return a subclass of Maps.FilteredKeyMap for slightly better
2180    // performance.
2181    return filterEntries(unfiltered, Maps.<K>keyPredicateOnEntries(keyPredicate));
2182  }
2183
2184  /**
2185   * Returns a navigable map containing the mappings in {@code unfiltered} whose keys satisfy a
2186   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2187   * other.
2188   *
2189   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2190   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2191   * and its views. When given a key that doesn't satisfy the predicate, the map's {@code put()} and
2192   * {@code putAll()} methods throw an {@link IllegalArgumentException}.
2193   *
2194   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2195   * or its views, only mappings whose keys satisfy the filter will be removed from the underlying
2196   * map.
2197   *
2198   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2199   *
2200   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2201   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2202   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2203   *
2204   * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>, as documented at
2205   * {@link Predicate#apply}. Do not provide a predicate such as {@code
2206   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2207   *
2208   * @since 14.0
2209   */
2210  @GwtIncompatible // NavigableMap
2211  public static <K, V> NavigableMap<K, V> filterKeys(
2212      NavigableMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2213    // TODO(lowasser): Return a subclass of Maps.FilteredKeyMap for slightly better
2214    // performance.
2215    return filterEntries(unfiltered, Maps.<K>keyPredicateOnEntries(keyPredicate));
2216  }
2217
2218  /**
2219   * Returns a bimap containing the mappings in {@code unfiltered} whose keys satisfy a predicate.
2220   * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
2221   *
2222   * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2223   * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
2224   * and its views. When given a key that doesn't satisfy the predicate, the bimap's {@code put()},
2225   * {@code forcePut()} and {@code putAll()} methods throw an {@link IllegalArgumentException}.
2226   *
2227   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2228   * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
2229   * bimap.
2230   *
2231   * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2232   *
2233   * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every key in
2234   * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
2235   * needed, it may be faster to copy the filtered bimap and use the copy.
2236   *
2237   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as documented
2238   * at {@link Predicate#apply}.
2239   *
2240   * @since 14.0
2241   */
2242  public static <K, V> BiMap<K, V> filterKeys(
2243      BiMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
2244    checkNotNull(keyPredicate);
2245    return filterEntries(unfiltered, Maps.<K>keyPredicateOnEntries(keyPredicate));
2246  }
2247
2248  /**
2249   * Returns a map containing the mappings in {@code unfiltered} whose values satisfy a predicate.
2250   * The returned map is a live view of {@code unfiltered}; changes to one affect the other.
2251   *
2252   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2253   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2254   * and its views. When given a value that doesn't satisfy the predicate, the map's {@code put()},
2255   * {@code putAll()}, and {@link Entry#setValue} methods throw an {@link IllegalArgumentException}.
2256   *
2257   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2258   * or its views, only mappings whose values satisfy the filter will be removed from the underlying
2259   * map.
2260   *
2261   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2262   *
2263   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2264   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2265   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2266   *
2267   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2268   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2269   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2270   */
2271  public static <K, V> Map<K, V> filterValues(
2272      Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2273    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2274  }
2275
2276  /**
2277   * Returns a sorted map containing the mappings in {@code unfiltered} whose values satisfy a
2278   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2279   * other.
2280   *
2281   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2282   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2283   * and its views. When given a value that doesn't satisfy the predicate, the map's {@code put()},
2284   * {@code putAll()}, and {@link Entry#setValue} methods throw an {@link IllegalArgumentException}.
2285   *
2286   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2287   * or its views, only mappings whose values satisfy the filter will be removed from the underlying
2288   * map.
2289   *
2290   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2291   *
2292   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2293   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2294   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2295   *
2296   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2297   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2298   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2299   *
2300   * @since 11.0
2301   */
2302  public static <K, V> SortedMap<K, V> filterValues(
2303      SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2304    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2305  }
2306
2307  /**
2308   * Returns a navigable map containing the mappings in {@code unfiltered} whose values satisfy a
2309   * predicate. The returned map is a live view of {@code unfiltered}; changes to one affect the
2310   * other.
2311   *
2312   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2313   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2314   * and its views. When given a value that doesn't satisfy the predicate, the map's {@code put()},
2315   * {@code putAll()}, and {@link Entry#setValue} methods throw an {@link IllegalArgumentException}.
2316   *
2317   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2318   * or its views, only mappings whose values satisfy the filter will be removed from the underlying
2319   * map.
2320   *
2321   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2322   *
2323   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2324   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2325   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2326   *
2327   * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with equals</i>, as documented
2328   * at {@link Predicate#apply}. Do not provide a predicate such as {@code
2329   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals.
2330   *
2331   * @since 14.0
2332   */
2333  @GwtIncompatible // NavigableMap
2334  public static <K, V> NavigableMap<K, V> filterValues(
2335      NavigableMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2336    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2337  }
2338
2339  /**
2340   * Returns a bimap containing the mappings in {@code unfiltered} whose values satisfy a predicate.
2341   * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
2342   *
2343   * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2344   * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
2345   * and its views. When given a value that doesn't satisfy the predicate, the bimap's {@code
2346   * put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
2347   * IllegalArgumentException}. Similarly, the map's entries have a {@link Entry#setValue} method
2348   * that throws an {@link IllegalArgumentException} when the provided value doesn't satisfy the
2349   * predicate.
2350   *
2351   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2352   * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
2353   * bimap.
2354   *
2355   * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2356   *
2357   * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every value in
2358   * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
2359   * needed, it may be faster to copy the filtered bimap and use the copy.
2360   *
2361   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as documented
2362   * at {@link Predicate#apply}.
2363   *
2364   * @since 14.0
2365   */
2366  public static <K, V> BiMap<K, V> filterValues(
2367      BiMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
2368    return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
2369  }
2370
2371  /**
2372   * Returns a map containing the mappings in {@code unfiltered} that satisfy a predicate. The
2373   * returned map is a live view of {@code unfiltered}; changes to one affect the other.
2374   *
2375   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2376   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2377   * and its views. When given a key/value pair that doesn't satisfy the predicate, the map's {@code
2378   * put()} and {@code putAll()} methods throw an {@link IllegalArgumentException}. Similarly, the
2379   * map's entries have a {@link Entry#setValue} method that throws an {@link
2380   * IllegalArgumentException} when the existing key and the provided value don't satisfy the
2381   * predicate.
2382   *
2383   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2384   * or its views, only mappings that satisfy the filter will be removed from the underlying map.
2385   *
2386   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2387   *
2388   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2389   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2390   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2391   *
2392   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2393   * at {@link Predicate#apply}.
2394   */
2395  public static <K, V> Map<K, V> filterEntries(
2396      Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2397    checkNotNull(entryPredicate);
2398    return (unfiltered instanceof AbstractFilteredMap)
2399        ? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
2400        : new FilteredEntryMap<K, V>(checkNotNull(unfiltered), entryPredicate);
2401  }
2402
2403  /**
2404   * Returns a sorted map containing the mappings in {@code unfiltered} that satisfy a predicate.
2405   * The returned map is a live view of {@code unfiltered}; changes to one affect the other.
2406   *
2407   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2408   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2409   * and its views. When given a key/value pair that doesn't satisfy the predicate, the map's {@code
2410   * put()} and {@code putAll()} methods throw an {@link IllegalArgumentException}. Similarly, the
2411   * map's entries have a {@link Entry#setValue} method that throws an {@link
2412   * IllegalArgumentException} when the existing key and the provided value don't satisfy the
2413   * predicate.
2414   *
2415   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2416   * or its views, only mappings that satisfy the filter will be removed from the underlying map.
2417   *
2418   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2419   *
2420   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2421   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2422   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2423   *
2424   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2425   * at {@link Predicate#apply}.
2426   *
2427   * @since 11.0
2428   */
2429  public static <K, V> SortedMap<K, V> filterEntries(
2430      SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2431    checkNotNull(entryPredicate);
2432    return (unfiltered instanceof FilteredEntrySortedMap)
2433        ? filterFiltered((FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate)
2434        : new FilteredEntrySortedMap<K, V>(checkNotNull(unfiltered), entryPredicate);
2435  }
2436
2437  /**
2438   * Returns a sorted map containing the mappings in {@code unfiltered} that satisfy a predicate.
2439   * The returned map is a live view of {@code unfiltered}; changes to one affect the other.
2440   *
2441   * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2442   * iterators that don't support {@code remove()}, but all other methods are supported by the map
2443   * and its views. When given a key/value pair that doesn't satisfy the predicate, the map's {@code
2444   * put()} and {@code putAll()} methods throw an {@link IllegalArgumentException}. Similarly, the
2445   * map's entries have a {@link Entry#setValue} method that throws an {@link
2446   * IllegalArgumentException} when the existing key and the provided value don't satisfy the
2447   * predicate.
2448   *
2449   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered map
2450   * or its views, only mappings that satisfy the filter will be removed from the underlying map.
2451   *
2452   * <p>The returned map isn't threadsafe or serializable, even if {@code unfiltered} is.
2453   *
2454   * <p>Many of the filtered map's methods, such as {@code size()}, iterate across every key/value
2455   * mapping in the underlying map and determine which satisfy the filter. When a live view is
2456   * <i>not</i> needed, it may be faster to copy the filtered map and use the copy.
2457   *
2458   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals</i>, as documented
2459   * at {@link Predicate#apply}.
2460   *
2461   * @since 14.0
2462   */
2463  @GwtIncompatible // NavigableMap
2464  public static <K, V> NavigableMap<K, V> filterEntries(
2465      NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2466    checkNotNull(entryPredicate);
2467    return (unfiltered instanceof FilteredEntryNavigableMap)
2468        ? filterFiltered((FilteredEntryNavigableMap<K, V>) unfiltered, entryPredicate)
2469        : new FilteredEntryNavigableMap<K, V>(checkNotNull(unfiltered), entryPredicate);
2470  }
2471
2472  /**
2473   * Returns a bimap containing the mappings in {@code unfiltered} that satisfy a predicate. The
2474   * returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
2475   *
2476   * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
2477   * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
2478   * and its views. When given a key/value pair that doesn't satisfy the predicate, the bimap's
2479   * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
2480   * IllegalArgumentException}. Similarly, the map's entries have an {@link Entry#setValue} method
2481   * that throws an {@link IllegalArgumentException} when the existing key and the provided value
2482   * don't satisfy the predicate.
2483   *
2484   * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
2485   * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
2486   * bimap.
2487   *
2488   * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
2489   *
2490   * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every key/value
2491   * mapping in the underlying bimap and determine which satisfy the filter. When a live view is
2492   * <i>not</i> needed, it may be faster to copy the filtered bimap and use the copy.
2493   *
2494   * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as documented
2495   * at {@link Predicate#apply}.
2496   *
2497   * @since 14.0
2498   */
2499  public static <K, V> BiMap<K, V> filterEntries(
2500      BiMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2501    checkNotNull(unfiltered);
2502    checkNotNull(entryPredicate);
2503    return (unfiltered instanceof FilteredEntryBiMap)
2504        ? filterFiltered((FilteredEntryBiMap<K, V>) unfiltered, entryPredicate)
2505        : new FilteredEntryBiMap<K, V>(unfiltered, entryPredicate);
2506  }
2507
2508  /**
2509   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2510   * map.
2511   */
2512  private static <K, V> Map<K, V> filterFiltered(
2513      AbstractFilteredMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2514    return new FilteredEntryMap<>(
2515        map.unfiltered, Predicates.<Entry<K, V>>and(map.predicate, entryPredicate));
2516  }
2517
2518  /**
2519   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2520   * sorted map.
2521   */
2522  private static <K, V> SortedMap<K, V> filterFiltered(
2523      FilteredEntrySortedMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2524    Predicate<Entry<K, V>> predicate = Predicates.<Entry<K, V>>and(map.predicate, entryPredicate);
2525    return new FilteredEntrySortedMap<>(map.sortedMap(), predicate);
2526  }
2527
2528  /**
2529   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2530   * navigable map.
2531   */
2532  @GwtIncompatible // NavigableMap
2533  private static <K, V> NavigableMap<K, V> filterFiltered(
2534      FilteredEntryNavigableMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2535    Predicate<Entry<K, V>> predicate =
2536        Predicates.<Entry<K, V>>and(map.entryPredicate, entryPredicate);
2537    return new FilteredEntryNavigableMap<>(map.unfiltered, predicate);
2538  }
2539
2540  /**
2541   * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when filtering a filtered
2542   * map.
2543   */
2544  private static <K, V> BiMap<K, V> filterFiltered(
2545      FilteredEntryBiMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
2546    Predicate<Entry<K, V>> predicate = Predicates.<Entry<K, V>>and(map.predicate, entryPredicate);
2547    return new FilteredEntryBiMap<>(map.unfiltered(), predicate);
2548  }
2549
2550  private abstract static class AbstractFilteredMap<K, V> extends ViewCachingAbstractMap<K, V> {
2551    final Map<K, V> unfiltered;
2552    final Predicate<? super Entry<K, V>> predicate;
2553
2554    AbstractFilteredMap(Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
2555      this.unfiltered = unfiltered;
2556      this.predicate = predicate;
2557    }
2558
2559    boolean apply(@NullableDecl Object key, @NullableDecl V value) {
2560      // This method is called only when the key is in the map, implying that
2561      // key is a K.
2562      @SuppressWarnings("unchecked")
2563      K k = (K) key;
2564      return predicate.apply(Maps.immutableEntry(k, value));
2565    }
2566
2567    @Override
2568    public V put(K key, V value) {
2569      checkArgument(apply(key, value));
2570      return unfiltered.put(key, value);
2571    }
2572
2573    @Override
2574    public void putAll(Map<? extends K, ? extends V> map) {
2575      for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
2576        checkArgument(apply(entry.getKey(), entry.getValue()));
2577      }
2578      unfiltered.putAll(map);
2579    }
2580
2581    @Override
2582    public boolean containsKey(Object key) {
2583      return unfiltered.containsKey(key) && apply(key, unfiltered.get(key));
2584    }
2585
2586    @Override
2587    public V get(Object key) {
2588      V value = unfiltered.get(key);
2589      return ((value != null) && apply(key, value)) ? value : null;
2590    }
2591
2592    @Override
2593    public boolean isEmpty() {
2594      return entrySet().isEmpty();
2595    }
2596
2597    @Override
2598    public V remove(Object key) {
2599      return containsKey(key) ? unfiltered.remove(key) : null;
2600    }
2601
2602    @Override
2603    Collection<V> createValues() {
2604      return new FilteredMapValues<>(this, unfiltered, predicate);
2605    }
2606  }
2607
2608  private static final class FilteredMapValues<K, V> extends Maps.Values<K, V> {
2609    final Map<K, V> unfiltered;
2610    final Predicate<? super Entry<K, V>> predicate;
2611
2612    FilteredMapValues(
2613        Map<K, V> filteredMap, Map<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
2614      super(filteredMap);
2615      this.unfiltered = unfiltered;
2616      this.predicate = predicate;
2617    }
2618
2619    @Override
2620    public boolean remove(Object o) {
2621      Iterator<Entry<K, V>> entryItr = unfiltered.entrySet().iterator();
2622      while (entryItr.hasNext()) {
2623        Entry<K, V> entry = entryItr.next();
2624        if (predicate.apply(entry) && Objects.equal(entry.getValue(), o)) {
2625          entryItr.remove();
2626          return true;
2627        }
2628      }
2629      return false;
2630    }
2631
2632    @Override
2633    public boolean removeAll(Collection<?> collection) {
2634      Iterator<Entry<K, V>> entryItr = unfiltered.entrySet().iterator();
2635      boolean result = false;
2636      while (entryItr.hasNext()) {
2637        Entry<K, V> entry = entryItr.next();
2638        if (predicate.apply(entry) && collection.contains(entry.getValue())) {
2639          entryItr.remove();
2640          result = true;
2641        }
2642      }
2643      return result;
2644    }
2645
2646    @Override
2647    public boolean retainAll(Collection<?> collection) {
2648      Iterator<Entry<K, V>> entryItr = unfiltered.entrySet().iterator();
2649      boolean result = false;
2650      while (entryItr.hasNext()) {
2651        Entry<K, V> entry = entryItr.next();
2652        if (predicate.apply(entry) && !collection.contains(entry.getValue())) {
2653          entryItr.remove();
2654          result = true;
2655        }
2656      }
2657      return result;
2658    }
2659
2660    @Override
2661    public Object[] toArray() {
2662      // creating an ArrayList so filtering happens once
2663      return Lists.newArrayList(iterator()).toArray();
2664    }
2665
2666    @Override
2667    public <T> T[] toArray(T[] array) {
2668      return Lists.newArrayList(iterator()).toArray(array);
2669    }
2670  }
2671
2672  private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> {
2673    final Predicate<? super K> keyPredicate;
2674
2675    FilteredKeyMap(
2676        Map<K, V> unfiltered,
2677        Predicate<? super K> keyPredicate,
2678        Predicate<? super Entry<K, V>> entryPredicate) {
2679      super(unfiltered, entryPredicate);
2680      this.keyPredicate = keyPredicate;
2681    }
2682
2683    @Override
2684    protected Set<Entry<K, V>> createEntrySet() {
2685      return Sets.filter(unfiltered.entrySet(), predicate);
2686    }
2687
2688    @Override
2689    Set<K> createKeySet() {
2690      return Sets.filter(unfiltered.keySet(), keyPredicate);
2691    }
2692
2693    // The cast is called only when the key is in the unfiltered map, implying
2694    // that key is a K.
2695    @Override
2696    @SuppressWarnings("unchecked")
2697    public boolean containsKey(Object key) {
2698      return unfiltered.containsKey(key) && keyPredicate.apply((K) key);
2699    }
2700  }
2701
2702  static class FilteredEntryMap<K, V> extends AbstractFilteredMap<K, V> {
2703    /**
2704     * Entries in this set satisfy the predicate, but they don't validate the input to {@code
2705     * Entry.setValue()}.
2706     */
2707    final Set<Entry<K, V>> filteredEntrySet;
2708
2709    FilteredEntryMap(Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2710      super(unfiltered, entryPredicate);
2711      filteredEntrySet = Sets.filter(unfiltered.entrySet(), predicate);
2712    }
2713
2714    @Override
2715    protected Set<Entry<K, V>> createEntrySet() {
2716      return new EntrySet();
2717    }
2718
2719    @WeakOuter
2720    private class EntrySet extends ForwardingSet<Entry<K, V>> {
2721      @Override
2722      protected Set<Entry<K, V>> delegate() {
2723        return filteredEntrySet;
2724      }
2725
2726      @Override
2727      public Iterator<Entry<K, V>> iterator() {
2728        return new TransformedIterator<Entry<K, V>, Entry<K, V>>(filteredEntrySet.iterator()) {
2729          @Override
2730          Entry<K, V> transform(final Entry<K, V> entry) {
2731            return new ForwardingMapEntry<K, V>() {
2732              @Override
2733              protected Entry<K, V> delegate() {
2734                return entry;
2735              }
2736
2737              @Override
2738              public V setValue(V newValue) {
2739                checkArgument(apply(getKey(), newValue));
2740                return super.setValue(newValue);
2741              }
2742            };
2743          }
2744        };
2745      }
2746    }
2747
2748    @Override
2749    Set<K> createKeySet() {
2750      return new KeySet();
2751    }
2752
2753    static <K, V> boolean removeAllKeys(
2754        Map<K, V> map, Predicate<? super Entry<K, V>> entryPredicate, Collection<?> keyCollection) {
2755      Iterator<Entry<K, V>> entryItr = map.entrySet().iterator();
2756      boolean result = false;
2757      while (entryItr.hasNext()) {
2758        Entry<K, V> entry = entryItr.next();
2759        if (entryPredicate.apply(entry) && keyCollection.contains(entry.getKey())) {
2760          entryItr.remove();
2761          result = true;
2762        }
2763      }
2764      return result;
2765    }
2766
2767    static <K, V> boolean retainAllKeys(
2768        Map<K, V> map, Predicate<? super Entry<K, V>> entryPredicate, Collection<?> keyCollection) {
2769      Iterator<Entry<K, V>> entryItr = map.entrySet().iterator();
2770      boolean result = false;
2771      while (entryItr.hasNext()) {
2772        Entry<K, V> entry = entryItr.next();
2773        if (entryPredicate.apply(entry) && !keyCollection.contains(entry.getKey())) {
2774          entryItr.remove();
2775          result = true;
2776        }
2777      }
2778      return result;
2779    }
2780
2781    @WeakOuter
2782    class KeySet extends Maps.KeySet<K, V> {
2783      KeySet() {
2784        super(FilteredEntryMap.this);
2785      }
2786
2787      @Override
2788      public boolean remove(Object o) {
2789        if (containsKey(o)) {
2790          unfiltered.remove(o);
2791          return true;
2792        }
2793        return false;
2794      }
2795
2796      @Override
2797      public boolean removeAll(Collection<?> collection) {
2798        return removeAllKeys(unfiltered, predicate, collection);
2799      }
2800
2801      @Override
2802      public boolean retainAll(Collection<?> collection) {
2803        return retainAllKeys(unfiltered, predicate, collection);
2804      }
2805
2806      @Override
2807      public Object[] toArray() {
2808        // creating an ArrayList so filtering happens once
2809        return Lists.newArrayList(iterator()).toArray();
2810      }
2811
2812      @Override
2813      public <T> T[] toArray(T[] array) {
2814        return Lists.newArrayList(iterator()).toArray(array);
2815      }
2816    }
2817  }
2818
2819  private static class FilteredEntrySortedMap<K, V> extends FilteredEntryMap<K, V>
2820      implements SortedMap<K, V> {
2821
2822    FilteredEntrySortedMap(
2823        SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2824      super(unfiltered, entryPredicate);
2825    }
2826
2827    SortedMap<K, V> sortedMap() {
2828      return (SortedMap<K, V>) unfiltered;
2829    }
2830
2831    @Override
2832    public SortedSet<K> keySet() {
2833      return (SortedSet<K>) super.keySet();
2834    }
2835
2836    @Override
2837    SortedSet<K> createKeySet() {
2838      return new SortedKeySet();
2839    }
2840
2841    @WeakOuter
2842    class SortedKeySet extends KeySet implements SortedSet<K> {
2843      @Override
2844      public Comparator<? super K> comparator() {
2845        return sortedMap().comparator();
2846      }
2847
2848      @Override
2849      public SortedSet<K> subSet(K fromElement, K toElement) {
2850        return (SortedSet<K>) subMap(fromElement, toElement).keySet();
2851      }
2852
2853      @Override
2854      public SortedSet<K> headSet(K toElement) {
2855        return (SortedSet<K>) headMap(toElement).keySet();
2856      }
2857
2858      @Override
2859      public SortedSet<K> tailSet(K fromElement) {
2860        return (SortedSet<K>) tailMap(fromElement).keySet();
2861      }
2862
2863      @Override
2864      public K first() {
2865        return firstKey();
2866      }
2867
2868      @Override
2869      public K last() {
2870        return lastKey();
2871      }
2872    }
2873
2874    @Override
2875    public Comparator<? super K> comparator() {
2876      return sortedMap().comparator();
2877    }
2878
2879    @Override
2880    public K firstKey() {
2881      // correctly throws NoSuchElementException when filtered map is empty.
2882      return keySet().iterator().next();
2883    }
2884
2885    @Override
2886    public K lastKey() {
2887      SortedMap<K, V> headMap = sortedMap();
2888      while (true) {
2889        // correctly throws NoSuchElementException when filtered map is empty.
2890        K key = headMap.lastKey();
2891        if (apply(key, unfiltered.get(key))) {
2892          return key;
2893        }
2894        headMap = sortedMap().headMap(key);
2895      }
2896    }
2897
2898    @Override
2899    public SortedMap<K, V> headMap(K toKey) {
2900      return new FilteredEntrySortedMap<>(sortedMap().headMap(toKey), predicate);
2901    }
2902
2903    @Override
2904    public SortedMap<K, V> subMap(K fromKey, K toKey) {
2905      return new FilteredEntrySortedMap<>(sortedMap().subMap(fromKey, toKey), predicate);
2906    }
2907
2908    @Override
2909    public SortedMap<K, V> tailMap(K fromKey) {
2910      return new FilteredEntrySortedMap<>(sortedMap().tailMap(fromKey), predicate);
2911    }
2912  }
2913
2914  @GwtIncompatible // NavigableMap
2915  private static class FilteredEntryNavigableMap<K, V> extends AbstractNavigableMap<K, V> {
2916    /*
2917     * It's less code to extend AbstractNavigableMap and forward the filtering logic to
2918     * FilteredEntryMap than to extend FilteredEntrySortedMap and reimplement all the NavigableMap
2919     * methods.
2920     */
2921
2922    private final NavigableMap<K, V> unfiltered;
2923    private final Predicate<? super Entry<K, V>> entryPredicate;
2924    private final Map<K, V> filteredDelegate;
2925
2926    FilteredEntryNavigableMap(
2927        NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
2928      this.unfiltered = checkNotNull(unfiltered);
2929      this.entryPredicate = entryPredicate;
2930      this.filteredDelegate = new FilteredEntryMap<>(unfiltered, entryPredicate);
2931    }
2932
2933    @Override
2934    public Comparator<? super K> comparator() {
2935      return unfiltered.comparator();
2936    }
2937
2938    @Override
2939    public NavigableSet<K> navigableKeySet() {
2940      return new Maps.NavigableKeySet<K, V>(this) {
2941        @Override
2942        public boolean removeAll(Collection<?> collection) {
2943          return FilteredEntryMap.removeAllKeys(unfiltered, entryPredicate, collection);
2944        }
2945
2946        @Override
2947        public boolean retainAll(Collection<?> collection) {
2948          return FilteredEntryMap.retainAllKeys(unfiltered, entryPredicate, collection);
2949        }
2950      };
2951    }
2952
2953    @Override
2954    public Collection<V> values() {
2955      return new FilteredMapValues<>(this, unfiltered, entryPredicate);
2956    }
2957
2958    @Override
2959    Iterator<Entry<K, V>> entryIterator() {
2960      return Iterators.filter(unfiltered.entrySet().iterator(), entryPredicate);
2961    }
2962
2963    @Override
2964    Iterator<Entry<K, V>> descendingEntryIterator() {
2965      return Iterators.filter(unfiltered.descendingMap().entrySet().iterator(), entryPredicate);
2966    }
2967
2968    @Override
2969    public int size() {
2970      return filteredDelegate.size();
2971    }
2972
2973    @Override
2974    public boolean isEmpty() {
2975      return !Iterables.any(unfiltered.entrySet(), entryPredicate);
2976    }
2977
2978    @Override
2979    @NullableDecl
2980    public V get(@NullableDecl Object key) {
2981      return filteredDelegate.get(key);
2982    }
2983
2984    @Override
2985    public boolean containsKey(@NullableDecl Object key) {
2986      return filteredDelegate.containsKey(key);
2987    }
2988
2989    @Override
2990    public V put(K key, V value) {
2991      return filteredDelegate.put(key, value);
2992    }
2993
2994    @Override
2995    public V remove(@NullableDecl Object key) {
2996      return filteredDelegate.remove(key);
2997    }
2998
2999    @Override
3000    public void putAll(Map<? extends K, ? extends V> m) {
3001      filteredDelegate.putAll(m);
3002    }
3003
3004    @Override
3005    public void clear() {
3006      filteredDelegate.clear();
3007    }
3008
3009    @Override
3010    public Set<Entry<K, V>> entrySet() {
3011      return filteredDelegate.entrySet();
3012    }
3013
3014    @Override
3015    public Entry<K, V> pollFirstEntry() {
3016      return Iterables.removeFirstMatching(unfiltered.entrySet(), entryPredicate);
3017    }
3018
3019    @Override
3020    public Entry<K, V> pollLastEntry() {
3021      return Iterables.removeFirstMatching(unfiltered.descendingMap().entrySet(), entryPredicate);
3022    }
3023
3024    @Override
3025    public NavigableMap<K, V> descendingMap() {
3026      return filterEntries(unfiltered.descendingMap(), entryPredicate);
3027    }
3028
3029    @Override
3030    public NavigableMap<K, V> subMap(
3031        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
3032      return filterEntries(
3033          unfiltered.subMap(fromKey, fromInclusive, toKey, toInclusive), entryPredicate);
3034    }
3035
3036    @Override
3037    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
3038      return filterEntries(unfiltered.headMap(toKey, inclusive), entryPredicate);
3039    }
3040
3041    @Override
3042    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
3043      return filterEntries(unfiltered.tailMap(fromKey, inclusive), entryPredicate);
3044    }
3045  }
3046
3047  static final class FilteredEntryBiMap<K, V> extends FilteredEntryMap<K, V>
3048      implements BiMap<K, V> {
3049    @RetainedWith private final BiMap<V, K> inverse;
3050
3051    private static <K, V> Predicate<Entry<V, K>> inversePredicate(
3052        final Predicate<? super Entry<K, V>> forwardPredicate) {
3053      return new Predicate<Entry<V, K>>() {
3054        @Override
3055        public boolean apply(Entry<V, K> input) {
3056          return forwardPredicate.apply(Maps.immutableEntry(input.getValue(), input.getKey()));
3057        }
3058      };
3059    }
3060
3061    FilteredEntryBiMap(BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate) {
3062      super(delegate, predicate);
3063      this.inverse =
3064          new FilteredEntryBiMap<>(delegate.inverse(), inversePredicate(predicate), this);
3065    }
3066
3067    private FilteredEntryBiMap(
3068        BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate, BiMap<V, K> inverse) {
3069      super(delegate, predicate);
3070      this.inverse = inverse;
3071    }
3072
3073    BiMap<K, V> unfiltered() {
3074      return (BiMap<K, V>) unfiltered;
3075    }
3076
3077    @Override
3078    public V forcePut(@NullableDecl K key, @NullableDecl V value) {
3079      checkArgument(apply(key, value));
3080      return unfiltered().forcePut(key, value);
3081    }
3082
3083    @Override
3084    public BiMap<V, K> inverse() {
3085      return inverse;
3086    }
3087
3088    @Override
3089    public Set<V> values() {
3090      return inverse.keySet();
3091    }
3092  }
3093
3094  /**
3095   * Returns an unmodifiable view of the specified navigable map. Query operations on the returned
3096   * map read through to the specified map, and attempts to modify the returned map, whether direct
3097   * or via its views, result in an {@code UnsupportedOperationException}.
3098   *
3099   * <p>The returned navigable map will be serializable if the specified navigable map is
3100   * serializable.
3101   *
3102   * <p>This method's signature will not permit you to convert a {@code NavigableMap<? extends K,
3103   * V>} to a {@code NavigableMap<K, V>}. If it permitted this, the returned map's {@code
3104   * comparator()} method might return a {@code Comparator<? extends K>}, which works only on a
3105   * particular subtype of {@code K}, but promise that it's a {@code Comparator<? super K>}, which
3106   * must work on any type of {@code K}.
3107   *
3108   * @param map the navigable map for which an unmodifiable view is to be returned
3109   * @return an unmodifiable view of the specified navigable map
3110   * @since 12.0
3111   */
3112  @GwtIncompatible // NavigableMap
3113  public static <K, V> NavigableMap<K, V> unmodifiableNavigableMap(
3114      NavigableMap<K, ? extends V> map) {
3115    checkNotNull(map);
3116    if (map instanceof UnmodifiableNavigableMap) {
3117      @SuppressWarnings("unchecked") // covariant
3118      NavigableMap<K, V> result = (NavigableMap) map;
3119      return result;
3120    } else {
3121      return new UnmodifiableNavigableMap<>(map);
3122    }
3123  }
3124
3125  @NullableDecl
3126  private static <K, V> Entry<K, V> unmodifiableOrNull(@NullableDecl Entry<K, ? extends V> entry) {
3127    return (entry == null) ? null : Maps.unmodifiableEntry(entry);
3128  }
3129
3130  @GwtIncompatible // NavigableMap
3131  static class UnmodifiableNavigableMap<K, V> extends ForwardingSortedMap<K, V>
3132      implements NavigableMap<K, V>, Serializable {
3133    private final NavigableMap<K, ? extends V> delegate;
3134
3135    UnmodifiableNavigableMap(NavigableMap<K, ? extends V> delegate) {
3136      this.delegate = delegate;
3137    }
3138
3139    UnmodifiableNavigableMap(
3140        NavigableMap<K, ? extends V> delegate, UnmodifiableNavigableMap<K, V> descendingMap) {
3141      this.delegate = delegate;
3142      this.descendingMap = descendingMap;
3143    }
3144
3145    @Override
3146    protected SortedMap<K, V> delegate() {
3147      return Collections.unmodifiableSortedMap(delegate);
3148    }
3149
3150    @Override
3151    public Entry<K, V> lowerEntry(K key) {
3152      return unmodifiableOrNull(delegate.lowerEntry(key));
3153    }
3154
3155    @Override
3156    public K lowerKey(K key) {
3157      return delegate.lowerKey(key);
3158    }
3159
3160    @Override
3161    public Entry<K, V> floorEntry(K key) {
3162      return unmodifiableOrNull(delegate.floorEntry(key));
3163    }
3164
3165    @Override
3166    public K floorKey(K key) {
3167      return delegate.floorKey(key);
3168    }
3169
3170    @Override
3171    public Entry<K, V> ceilingEntry(K key) {
3172      return unmodifiableOrNull(delegate.ceilingEntry(key));
3173    }
3174
3175    @Override
3176    public K ceilingKey(K key) {
3177      return delegate.ceilingKey(key);
3178    }
3179
3180    @Override
3181    public Entry<K, V> higherEntry(K key) {
3182      return unmodifiableOrNull(delegate.higherEntry(key));
3183    }
3184
3185    @Override
3186    public K higherKey(K key) {
3187      return delegate.higherKey(key);
3188    }
3189
3190    @Override
3191    public Entry<K, V> firstEntry() {
3192      return unmodifiableOrNull(delegate.firstEntry());
3193    }
3194
3195    @Override
3196    public Entry<K, V> lastEntry() {
3197      return unmodifiableOrNull(delegate.lastEntry());
3198    }
3199
3200    @Override
3201    public final Entry<K, V> pollFirstEntry() {
3202      throw new UnsupportedOperationException();
3203    }
3204
3205    @Override
3206    public final Entry<K, V> pollLastEntry() {
3207      throw new UnsupportedOperationException();
3208    }
3209
3210    @MonotonicNonNullDecl private transient UnmodifiableNavigableMap<K, V> descendingMap;
3211
3212    @Override
3213    public NavigableMap<K, V> descendingMap() {
3214      UnmodifiableNavigableMap<K, V> result = descendingMap;
3215      return (result == null)
3216          ? descendingMap = new UnmodifiableNavigableMap<>(delegate.descendingMap(), this)
3217          : result;
3218    }
3219
3220    @Override
3221    public Set<K> keySet() {
3222      return navigableKeySet();
3223    }
3224
3225    @Override
3226    public NavigableSet<K> navigableKeySet() {
3227      return Sets.unmodifiableNavigableSet(delegate.navigableKeySet());
3228    }
3229
3230    @Override
3231    public NavigableSet<K> descendingKeySet() {
3232      return Sets.unmodifiableNavigableSet(delegate.descendingKeySet());
3233    }
3234
3235    @Override
3236    public SortedMap<K, V> subMap(K fromKey, K toKey) {
3237      return subMap(fromKey, true, toKey, false);
3238    }
3239
3240    @Override
3241    public NavigableMap<K, V> subMap(
3242        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
3243      return Maps.unmodifiableNavigableMap(
3244          delegate.subMap(fromKey, fromInclusive, toKey, toInclusive));
3245    }
3246
3247    @Override
3248    public SortedMap<K, V> headMap(K toKey) {
3249      return headMap(toKey, false);
3250    }
3251
3252    @Override
3253    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
3254      return Maps.unmodifiableNavigableMap(delegate.headMap(toKey, inclusive));
3255    }
3256
3257    @Override
3258    public SortedMap<K, V> tailMap(K fromKey) {
3259      return tailMap(fromKey, true);
3260    }
3261
3262    @Override
3263    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
3264      return Maps.unmodifiableNavigableMap(delegate.tailMap(fromKey, inclusive));
3265    }
3266  }
3267
3268  /**
3269   * Returns a synchronized (thread-safe) navigable map backed by the specified navigable map. In
3270   * order to guarantee serial access, it is critical that <b>all</b> access to the backing
3271   * navigable map is accomplished through the returned navigable map (or its views).
3272   *
3273   * <p>It is imperative that the user manually synchronize on the returned navigable map when
3274   * iterating over any of its collection views, or the collections views of any of its {@code
3275   * descendingMap}, {@code subMap}, {@code headMap} or {@code tailMap} views.
3276   *
3277   * <pre>{@code
3278   * NavigableMap<K, V> map = synchronizedNavigableMap(new TreeMap<K, V>());
3279   *
3280   * // Needn't be in synchronized block
3281   * NavigableSet<K> set = map.navigableKeySet();
3282   *
3283   * synchronized (map) { // Synchronizing on map, not set!
3284   *   Iterator<K> it = set.iterator(); // Must be in synchronized block
3285   *   while (it.hasNext()) {
3286   *     foo(it.next());
3287   *   }
3288   * }
3289   * }</pre>
3290   *
3291   * <p>or:
3292   *
3293   * <pre>{@code
3294   * NavigableMap<K, V> map = synchronizedNavigableMap(new TreeMap<K, V>());
3295   * NavigableMap<K, V> map2 = map.subMap(foo, false, bar, true);
3296   *
3297   * // Needn't be in synchronized block
3298   * NavigableSet<K> set2 = map2.descendingKeySet();
3299   *
3300   * synchronized (map) { // Synchronizing on map, not map2 or set2!
3301   *   Iterator<K> it = set2.iterator(); // Must be in synchronized block
3302   *   while (it.hasNext()) {
3303   *     foo(it.next());
3304   *   }
3305   * }
3306   * }</pre>
3307   *
3308   * <p>Failure to follow this advice may result in non-deterministic behavior.
3309   *
3310   * <p>The returned navigable map will be serializable if the specified navigable map is
3311   * serializable.
3312   *
3313   * @param navigableMap the navigable map to be "wrapped" in a synchronized navigable map.
3314   * @return a synchronized view of the specified navigable map.
3315   * @since 13.0
3316   */
3317  @GwtIncompatible // NavigableMap
3318  public static <K, V> NavigableMap<K, V> synchronizedNavigableMap(
3319      NavigableMap<K, V> navigableMap) {
3320    return Synchronized.navigableMap(navigableMap);
3321  }
3322
3323  /**
3324   * {@code AbstractMap} extension that makes it easy to cache customized keySet, values, and
3325   * entrySet views.
3326   */
3327  @GwtCompatible
3328  abstract static class ViewCachingAbstractMap<K, V> extends AbstractMap<K, V> {
3329    /**
3330     * Creates the entry set to be returned by {@link #entrySet()}. This method is invoked at most
3331     * once on a given map, at the time when {@code entrySet} is first called.
3332     */
3333    abstract Set<Entry<K, V>> createEntrySet();
3334
3335    @MonotonicNonNullDecl private transient Set<Entry<K, V>> entrySet;
3336
3337    @Override
3338    public Set<Entry<K, V>> entrySet() {
3339      Set<Entry<K, V>> result = entrySet;
3340      return (result == null) ? entrySet = createEntrySet() : result;
3341    }
3342
3343    @MonotonicNonNullDecl private transient Set<K> keySet;
3344
3345    @Override
3346    public Set<K> keySet() {
3347      Set<K> result = keySet;
3348      return (result == null) ? keySet = createKeySet() : result;
3349    }
3350
3351    Set<K> createKeySet() {
3352      return new KeySet<>(this);
3353    }
3354
3355    @MonotonicNonNullDecl private transient Collection<V> values;
3356
3357    @Override
3358    public Collection<V> values() {
3359      Collection<V> result = values;
3360      return (result == null) ? values = createValues() : result;
3361    }
3362
3363    Collection<V> createValues() {
3364      return new Values<>(this);
3365    }
3366  }
3367
3368  abstract static class IteratorBasedAbstractMap<K, V> extends AbstractMap<K, V> {
3369    @Override
3370    public abstract int size();
3371
3372    abstract Iterator<Entry<K, V>> entryIterator();
3373
3374    @Override
3375    public Set<Entry<K, V>> entrySet() {
3376      return new EntrySet<K, V>() {
3377        @Override
3378        Map<K, V> map() {
3379          return IteratorBasedAbstractMap.this;
3380        }
3381
3382        @Override
3383        public Iterator<Entry<K, V>> iterator() {
3384          return entryIterator();
3385        }
3386      };
3387    }
3388
3389    @Override
3390    public void clear() {
3391      Iterators.clear(entryIterator());
3392    }
3393  }
3394
3395  /**
3396   * Delegates to {@link Map#get}. Returns {@code null} on {@code ClassCastException} and {@code
3397   * NullPointerException}.
3398   */
3399  static <V> V safeGet(Map<?, V> map, @NullableDecl Object key) {
3400    checkNotNull(map);
3401    try {
3402      return map.get(key);
3403    } catch (ClassCastException | NullPointerException e) {
3404      return null;
3405    }
3406  }
3407
3408  /**
3409   * Delegates to {@link Map#containsKey}. Returns {@code false} on {@code ClassCastException} and
3410   * {@code NullPointerException}.
3411   */
3412  static boolean safeContainsKey(Map<?, ?> map, Object key) {
3413    checkNotNull(map);
3414    try {
3415      return map.containsKey(key);
3416    } catch (ClassCastException | NullPointerException e) {
3417      return false;
3418    }
3419  }
3420
3421  /**
3422   * Delegates to {@link Map#remove}. Returns {@code null} on {@code ClassCastException} and {@code
3423   * NullPointerException}.
3424   */
3425  static <V> V safeRemove(Map<?, V> map, Object key) {
3426    checkNotNull(map);
3427    try {
3428      return map.remove(key);
3429    } catch (ClassCastException | NullPointerException e) {
3430      return null;
3431    }
3432  }
3433
3434  /** An admittedly inefficient implementation of {@link Map#containsKey}. */
3435  static boolean containsKeyImpl(Map<?, ?> map, @NullableDecl Object key) {
3436    return Iterators.contains(keyIterator(map.entrySet().iterator()), key);
3437  }
3438
3439  /** An implementation of {@link Map#containsValue}. */
3440  static boolean containsValueImpl(Map<?, ?> map, @NullableDecl Object value) {
3441    return Iterators.contains(valueIterator(map.entrySet().iterator()), value);
3442  }
3443
3444  /**
3445   * Implements {@code Collection.contains} safely for forwarding collections of map entries. If
3446   * {@code o} is an instance of {@code Entry}, it is wrapped using {@link #unmodifiableEntry} to
3447   * protect against a possible nefarious equals method.
3448   *
3449   * <p>Note that {@code c} is the backing (delegate) collection, rather than the forwarding
3450   * collection.
3451   *
3452   * @param c the delegate (unwrapped) collection of map entries
3453   * @param o the object that might be contained in {@code c}
3454   * @return {@code true} if {@code c} contains {@code o}
3455   */
3456  static <K, V> boolean containsEntryImpl(Collection<Entry<K, V>> c, Object o) {
3457    if (!(o instanceof Entry)) {
3458      return false;
3459    }
3460    return c.contains(unmodifiableEntry((Entry<?, ?>) o));
3461  }
3462
3463  /**
3464   * Implements {@code Collection.remove} safely for forwarding collections of map entries. If
3465   * {@code o} is an instance of {@code Entry}, it is wrapped using {@link #unmodifiableEntry} to
3466   * protect against a possible nefarious equals method.
3467   *
3468   * <p>Note that {@code c} is backing (delegate) collection, rather than the forwarding collection.
3469   *
3470   * @param c the delegate (unwrapped) collection of map entries
3471   * @param o the object to remove from {@code c}
3472   * @return {@code true} if {@code c} was changed
3473   */
3474  static <K, V> boolean removeEntryImpl(Collection<Entry<K, V>> c, Object o) {
3475    if (!(o instanceof Entry)) {
3476      return false;
3477    }
3478    return c.remove(unmodifiableEntry((Entry<?, ?>) o));
3479  }
3480
3481  /** An implementation of {@link Map#equals}. */
3482  static boolean equalsImpl(Map<?, ?> map, Object object) {
3483    if (map == object) {
3484      return true;
3485    } else if (object instanceof Map) {
3486      Map<?, ?> o = (Map<?, ?>) object;
3487      return map.entrySet().equals(o.entrySet());
3488    }
3489    return false;
3490  }
3491
3492  /** An implementation of {@link Map#toString}. */
3493  static String toStringImpl(Map<?, ?> map) {
3494    StringBuilder sb = Collections2.newStringBuilderForCollection(map.size()).append('{');
3495    boolean first = true;
3496    for (Entry<?, ?> entry : map.entrySet()) {
3497      if (!first) {
3498        sb.append(", ");
3499      }
3500      first = false;
3501      sb.append(entry.getKey()).append('=').append(entry.getValue());
3502    }
3503    return sb.append('}').toString();
3504  }
3505
3506  /** An implementation of {@link Map#putAll}. */
3507  static <K, V> void putAllImpl(Map<K, V> self, Map<? extends K, ? extends V> map) {
3508    for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
3509      self.put(entry.getKey(), entry.getValue());
3510    }
3511  }
3512
3513  static class KeySet<K, V> extends Sets.ImprovedAbstractSet<K> {
3514    @Weak final Map<K, V> map;
3515
3516    KeySet(Map<K, V> map) {
3517      this.map = checkNotNull(map);
3518    }
3519
3520    Map<K, V> map() {
3521      return map;
3522    }
3523
3524    @Override
3525    public Iterator<K> iterator() {
3526      return keyIterator(map().entrySet().iterator());
3527    }
3528
3529    @Override
3530    public int size() {
3531      return map().size();
3532    }
3533
3534    @Override
3535    public boolean isEmpty() {
3536      return map().isEmpty();
3537    }
3538
3539    @Override
3540    public boolean contains(Object o) {
3541      return map().containsKey(o);
3542    }
3543
3544    @Override
3545    public boolean remove(Object o) {
3546      if (contains(o)) {
3547        map().remove(o);
3548        return true;
3549      }
3550      return false;
3551    }
3552
3553    @Override
3554    public void clear() {
3555      map().clear();
3556    }
3557  }
3558
3559  @NullableDecl
3560  static <K> K keyOrNull(@NullableDecl Entry<K, ?> entry) {
3561    return (entry == null) ? null : entry.getKey();
3562  }
3563
3564  @NullableDecl
3565  static <V> V valueOrNull(@NullableDecl Entry<?, V> entry) {
3566    return (entry == null) ? null : entry.getValue();
3567  }
3568
3569  static class SortedKeySet<K, V> extends KeySet<K, V> implements SortedSet<K> {
3570    SortedKeySet(SortedMap<K, V> map) {
3571      super(map);
3572    }
3573
3574    @Override
3575    SortedMap<K, V> map() {
3576      return (SortedMap<K, V>) super.map();
3577    }
3578
3579    @Override
3580    public Comparator<? super K> comparator() {
3581      return map().comparator();
3582    }
3583
3584    @Override
3585    public SortedSet<K> subSet(K fromElement, K toElement) {
3586      return new SortedKeySet<>(map().subMap(fromElement, toElement));
3587    }
3588
3589    @Override
3590    public SortedSet<K> headSet(K toElement) {
3591      return new SortedKeySet<>(map().headMap(toElement));
3592    }
3593
3594    @Override
3595    public SortedSet<K> tailSet(K fromElement) {
3596      return new SortedKeySet<>(map().tailMap(fromElement));
3597    }
3598
3599    @Override
3600    public K first() {
3601      return map().firstKey();
3602    }
3603
3604    @Override
3605    public K last() {
3606      return map().lastKey();
3607    }
3608  }
3609
3610  @GwtIncompatible // NavigableMap
3611  static class NavigableKeySet<K, V> extends SortedKeySet<K, V> implements NavigableSet<K> {
3612    NavigableKeySet(NavigableMap<K, V> map) {
3613      super(map);
3614    }
3615
3616    @Override
3617    NavigableMap<K, V> map() {
3618      return (NavigableMap<K, V>) map;
3619    }
3620
3621    @Override
3622    public K lower(K e) {
3623      return map().lowerKey(e);
3624    }
3625
3626    @Override
3627    public K floor(K e) {
3628      return map().floorKey(e);
3629    }
3630
3631    @Override
3632    public K ceiling(K e) {
3633      return map().ceilingKey(e);
3634    }
3635
3636    @Override
3637    public K higher(K e) {
3638      return map().higherKey(e);
3639    }
3640
3641    @Override
3642    public K pollFirst() {
3643      return keyOrNull(map().pollFirstEntry());
3644    }
3645
3646    @Override
3647    public K pollLast() {
3648      return keyOrNull(map().pollLastEntry());
3649    }
3650
3651    @Override
3652    public NavigableSet<K> descendingSet() {
3653      return map().descendingKeySet();
3654    }
3655
3656    @Override
3657    public Iterator<K> descendingIterator() {
3658      return descendingSet().iterator();
3659    }
3660
3661    @Override
3662    public NavigableSet<K> subSet(
3663        K fromElement, boolean fromInclusive, K toElement, boolean toInclusive) {
3664      return map().subMap(fromElement, fromInclusive, toElement, toInclusive).navigableKeySet();
3665    }
3666
3667    @Override
3668    public SortedSet<K> subSet(K fromElement, K toElement) {
3669      return subSet(fromElement, true, toElement, false);
3670    }
3671
3672    @Override
3673    public NavigableSet<K> headSet(K toElement, boolean inclusive) {
3674      return map().headMap(toElement, inclusive).navigableKeySet();
3675    }
3676
3677    @Override
3678    public SortedSet<K> headSet(K toElement) {
3679      return headSet(toElement, false);
3680    }
3681
3682    @Override
3683    public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
3684      return map().tailMap(fromElement, inclusive).navigableKeySet();
3685    }
3686
3687    @Override
3688    public SortedSet<K> tailSet(K fromElement) {
3689      return tailSet(fromElement, true);
3690    }
3691  }
3692
3693  static class Values<K, V> extends AbstractCollection<V> {
3694    @Weak final Map<K, V> map;
3695
3696    Values(Map<K, V> map) {
3697      this.map = checkNotNull(map);
3698    }
3699
3700    final Map<K, V> map() {
3701      return map;
3702    }
3703
3704    @Override
3705    public Iterator<V> iterator() {
3706      return valueIterator(map().entrySet().iterator());
3707    }
3708
3709    @Override
3710    public boolean remove(Object o) {
3711      try {
3712        return super.remove(o);
3713      } catch (UnsupportedOperationException e) {
3714        for (Entry<K, V> entry : map().entrySet()) {
3715          if (Objects.equal(o, entry.getValue())) {
3716            map().remove(entry.getKey());
3717            return true;
3718          }
3719        }
3720        return false;
3721      }
3722    }
3723
3724    @Override
3725    public boolean removeAll(Collection<?> c) {
3726      try {
3727        return super.removeAll(checkNotNull(c));
3728      } catch (UnsupportedOperationException e) {
3729        Set<K> toRemove = Sets.newHashSet();
3730        for (Entry<K, V> entry : map().entrySet()) {
3731          if (c.contains(entry.getValue())) {
3732            toRemove.add(entry.getKey());
3733          }
3734        }
3735        return map().keySet().removeAll(toRemove);
3736      }
3737    }
3738
3739    @Override
3740    public boolean retainAll(Collection<?> c) {
3741      try {
3742        return super.retainAll(checkNotNull(c));
3743      } catch (UnsupportedOperationException e) {
3744        Set<K> toRetain = Sets.newHashSet();
3745        for (Entry<K, V> entry : map().entrySet()) {
3746          if (c.contains(entry.getValue())) {
3747            toRetain.add(entry.getKey());
3748          }
3749        }
3750        return map().keySet().retainAll(toRetain);
3751      }
3752    }
3753
3754    @Override
3755    public int size() {
3756      return map().size();
3757    }
3758
3759    @Override
3760    public boolean isEmpty() {
3761      return map().isEmpty();
3762    }
3763
3764    @Override
3765    public boolean contains(@NullableDecl Object o) {
3766      return map().containsValue(o);
3767    }
3768
3769    @Override
3770    public void clear() {
3771      map().clear();
3772    }
3773  }
3774
3775  abstract static class EntrySet<K, V> extends Sets.ImprovedAbstractSet<Entry<K, V>> {
3776    abstract Map<K, V> map();
3777
3778    @Override
3779    public int size() {
3780      return map().size();
3781    }
3782
3783    @Override
3784    public void clear() {
3785      map().clear();
3786    }
3787
3788    @Override
3789    public boolean contains(Object o) {
3790      if (o instanceof Entry) {
3791        Entry<?, ?> entry = (Entry<?, ?>) o;
3792        Object key = entry.getKey();
3793        V value = Maps.safeGet(map(), key);
3794        return Objects.equal(value, entry.getValue()) && (value != null || map().containsKey(key));
3795      }
3796      return false;
3797    }
3798
3799    @Override
3800    public boolean isEmpty() {
3801      return map().isEmpty();
3802    }
3803
3804    @Override
3805    public boolean remove(Object o) {
3806      if (contains(o)) {
3807        Entry<?, ?> entry = (Entry<?, ?>) o;
3808        return map().keySet().remove(entry.getKey());
3809      }
3810      return false;
3811    }
3812
3813    @Override
3814    public boolean removeAll(Collection<?> c) {
3815      try {
3816        return super.removeAll(checkNotNull(c));
3817      } catch (UnsupportedOperationException e) {
3818        // if the iterators don't support remove
3819        return Sets.removeAllImpl(this, c.iterator());
3820      }
3821    }
3822
3823    @Override
3824    public boolean retainAll(Collection<?> c) {
3825      try {
3826        return super.retainAll(checkNotNull(c));
3827      } catch (UnsupportedOperationException e) {
3828        // if the iterators don't support remove
3829        Set<Object> keys = Sets.newHashSetWithExpectedSize(c.size());
3830        for (Object o : c) {
3831          if (contains(o)) {
3832            Entry<?, ?> entry = (Entry<?, ?>) o;
3833            keys.add(entry.getKey());
3834          }
3835        }
3836        return map().keySet().retainAll(keys);
3837      }
3838    }
3839  }
3840
3841  @GwtIncompatible // NavigableMap
3842  abstract static class DescendingMap<K, V> extends ForwardingMap<K, V>
3843      implements NavigableMap<K, V> {
3844
3845    abstract NavigableMap<K, V> forward();
3846
3847    @Override
3848    protected final Map<K, V> delegate() {
3849      return forward();
3850    }
3851
3852    @MonotonicNonNullDecl private transient Comparator<? super K> comparator;
3853
3854    @SuppressWarnings("unchecked")
3855    @Override
3856    public Comparator<? super K> comparator() {
3857      Comparator<? super K> result = comparator;
3858      if (result == null) {
3859        Comparator<? super K> forwardCmp = forward().comparator();
3860        if (forwardCmp == null) {
3861          forwardCmp = (Comparator) Ordering.natural();
3862        }
3863        result = comparator = reverse(forwardCmp);
3864      }
3865      return result;
3866    }
3867
3868    // If we inline this, we get a javac error.
3869    private static <T> Ordering<T> reverse(Comparator<T> forward) {
3870      return Ordering.from(forward).reverse();
3871    }
3872
3873    @Override
3874    public K firstKey() {
3875      return forward().lastKey();
3876    }
3877
3878    @Override
3879    public K lastKey() {
3880      return forward().firstKey();
3881    }
3882
3883    @Override
3884    public Entry<K, V> lowerEntry(K key) {
3885      return forward().higherEntry(key);
3886    }
3887
3888    @Override
3889    public K lowerKey(K key) {
3890      return forward().higherKey(key);
3891    }
3892
3893    @Override
3894    public Entry<K, V> floorEntry(K key) {
3895      return forward().ceilingEntry(key);
3896    }
3897
3898    @Override
3899    public K floorKey(K key) {
3900      return forward().ceilingKey(key);
3901    }
3902
3903    @Override
3904    public Entry<K, V> ceilingEntry(K key) {
3905      return forward().floorEntry(key);
3906    }
3907
3908    @Override
3909    public K ceilingKey(K key) {
3910      return forward().floorKey(key);
3911    }
3912
3913    @Override
3914    public Entry<K, V> higherEntry(K key) {
3915      return forward().lowerEntry(key);
3916    }
3917
3918    @Override
3919    public K higherKey(K key) {
3920      return forward().lowerKey(key);
3921    }
3922
3923    @Override
3924    public Entry<K, V> firstEntry() {
3925      return forward().lastEntry();
3926    }
3927
3928    @Override
3929    public Entry<K, V> lastEntry() {
3930      return forward().firstEntry();
3931    }
3932
3933    @Override
3934    public Entry<K, V> pollFirstEntry() {
3935      return forward().pollLastEntry();
3936    }
3937
3938    @Override
3939    public Entry<K, V> pollLastEntry() {
3940      return forward().pollFirstEntry();
3941    }
3942
3943    @Override
3944    public NavigableMap<K, V> descendingMap() {
3945      return forward();
3946    }
3947
3948    @MonotonicNonNullDecl private transient Set<Entry<K, V>> entrySet;
3949
3950    @Override
3951    public Set<Entry<K, V>> entrySet() {
3952      Set<Entry<K, V>> result = entrySet;
3953      return (result == null) ? entrySet = createEntrySet() : result;
3954    }
3955
3956    abstract Iterator<Entry<K, V>> entryIterator();
3957
3958    Set<Entry<K, V>> createEntrySet() {
3959      @WeakOuter
3960      class EntrySetImpl extends EntrySet<K, V> {
3961        @Override
3962        Map<K, V> map() {
3963          return DescendingMap.this;
3964        }
3965
3966        @Override
3967        public Iterator<Entry<K, V>> iterator() {
3968          return entryIterator();
3969        }
3970      }
3971      return new EntrySetImpl();
3972    }
3973
3974    @Override
3975    public Set<K> keySet() {
3976      return navigableKeySet();
3977    }
3978
3979    @MonotonicNonNullDecl private transient NavigableSet<K> navigableKeySet;
3980
3981    @Override
3982    public NavigableSet<K> navigableKeySet() {
3983      NavigableSet<K> result = navigableKeySet;
3984      return (result == null) ? navigableKeySet = new NavigableKeySet<>(this) : result;
3985    }
3986
3987    @Override
3988    public NavigableSet<K> descendingKeySet() {
3989      return forward().navigableKeySet();
3990    }
3991
3992    @Override
3993    public NavigableMap<K, V> subMap(
3994        K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
3995      return forward().subMap(toKey, toInclusive, fromKey, fromInclusive).descendingMap();
3996    }
3997
3998    @Override
3999    public SortedMap<K, V> subMap(K fromKey, K toKey) {
4000      return subMap(fromKey, true, toKey, false);
4001    }
4002
4003    @Override
4004    public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
4005      return forward().tailMap(toKey, inclusive).descendingMap();
4006    }
4007
4008    @Override
4009    public SortedMap<K, V> headMap(K toKey) {
4010      return headMap(toKey, false);
4011    }
4012
4013    @Override
4014    public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
4015      return forward().headMap(fromKey, inclusive).descendingMap();
4016    }
4017
4018    @Override
4019    public SortedMap<K, V> tailMap(K fromKey) {
4020      return tailMap(fromKey, true);
4021    }
4022
4023    @Override
4024    public Collection<V> values() {
4025      return new Values<>(this);
4026    }
4027
4028    @Override
4029    public String toString() {
4030      return standardToString();
4031    }
4032  }
4033
4034  /** Returns a map from the ith element of list to i. */
4035  static <E> ImmutableMap<E, Integer> indexMap(Collection<E> list) {
4036    ImmutableMap.Builder<E, Integer> builder = new ImmutableMap.Builder<>(list.size());
4037    int i = 0;
4038    for (E e : list) {
4039      builder.put(e, i++);
4040    }
4041    return builder.build();
4042  }
4043
4044  /**
4045   * Returns a view of the portion of {@code map} whose keys are contained by {@code range}.
4046   *
4047   * <p>This method delegates to the appropriate methods of {@link NavigableMap} (namely {@link
4048   * NavigableMap#subMap(Object, boolean, Object, boolean) subMap()}, {@link
4049   * NavigableMap#tailMap(Object, boolean) tailMap()}, and {@link NavigableMap#headMap(Object,
4050   * boolean) headMap()}) to actually construct the view. Consult these methods for a full
4051   * description of the returned view's behavior.
4052   *
4053   * <p><b>Warning:</b> {@code Range}s always represent a range of values using the values' natural
4054   * ordering. {@code NavigableMap} on the other hand can specify a custom ordering via a {@link
4055   * Comparator}, which can violate the natural ordering. Using this method (or in general using
4056   * {@code Range}) with unnaturally-ordered maps can lead to unexpected and undefined behavior.
4057   *
4058   * @since 20.0
4059   */
4060  @Beta
4061  @GwtIncompatible // NavigableMap
4062  public static <K extends Comparable<? super K>, V> NavigableMap<K, V> subMap(
4063      NavigableMap<K, V> map, Range<K> range) {
4064    if (map.comparator() != null
4065        && map.comparator() != Ordering.natural()
4066        && range.hasLowerBound()
4067        && range.hasUpperBound()) {
4068      checkArgument(
4069          map.comparator().compare(range.lowerEndpoint(), range.upperEndpoint()) <= 0,
4070          "map is using a custom comparator which is inconsistent with the natural ordering.");
4071    }
4072    if (range.hasLowerBound() && range.hasUpperBound()) {
4073      return map.subMap(
4074          range.lowerEndpoint(),
4075          range.lowerBoundType() == BoundType.CLOSED,
4076          range.upperEndpoint(),
4077          range.upperBoundType() == BoundType.CLOSED);
4078    } else if (range.hasLowerBound()) {
4079      return map.tailMap(range.lowerEndpoint(), range.lowerBoundType() == BoundType.CLOSED);
4080    } else if (range.hasUpperBound()) {
4081      return map.headMap(range.upperEndpoint(), range.upperBoundType() == BoundType.CLOSED);
4082    }
4083    return checkNotNull(map);
4084  }
4085}