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