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