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