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