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