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