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