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