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