11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.Maps.transformEntries;
207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.Maps.transformValues;
213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport static com.google.common.collect.Maps.unmodifiableNavigableMap;
227dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.testing.Helpers.mapEntry;
233ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport static com.google.common.truth.Truth.assertThat;
240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static java.util.Arrays.asList;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.base.Converter;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalence;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Functions;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.EntryTransformer;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.ValueDifferenceImpl;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.SetsTest.Derived;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.EqualsTester;
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester;
390888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.testing.SerializableTester;
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase;
427dd252788645e940eada959bdde927426e2531c9Paul Duffin
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException;
443ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport java.io.StringReader;
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.reflect.Field;
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays;
477dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collection;
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.EnumMap;
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Enumeration;
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.HashMap;
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.IdentityHashMap;
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap;
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
593ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport java.util.NavigableMap;
603ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport java.util.NavigableSet;
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Properties;
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap;
647dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.SortedSet;
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.TreeMap;
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ConcurrentMap;
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit test for {@code Maps}.
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class MapsTest extends TestCase {
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
780888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Comparator<Integer> SOME_COMPARATOR =
790888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Collections.reverseOrder();
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMap() {
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<Integer, Integer> map = Maps.newHashMap();
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMapWithInitialMap() {
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new TreeMap<String, Integer>();
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<String, Integer> map = Maps.newHashMap(original);
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMapGeneralizesTypes() {
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new TreeMap<String, Integer>();
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    HashMap<Object, Object> map =
1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.newHashMap((Map<? extends Object, ? extends Object>) original);
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCapacityForNegativeSizeFails() {
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.capacity(-1);
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Negative expected size must result in IllegalArgumentException");
1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IllegalArgumentException ex) {
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Tests that nHMWES makes hash maps large enough that adding the expected
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * number of elements won't cause a rehash.
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * As of jdk7u40, HashMap has an empty-map optimization.  The argument to
1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * new HashMap(int) is noted, but the initial table is a zero-length array.
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * This test may fail miserably on non-OpenJDK environments...
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("reflection")
1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testNewHashMapWithExpectedSize_wontGrow() throws Exception {
1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // before jdk7u40: creates one-bucket table
1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // after  jdk7u40: creates empty table
1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(bucketsOf(Maps.newHashMapWithExpectedSize(0)) <= 1);
1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (int size = 1; size < 200; size++) {
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      HashMap<Integer, Void> map1 = Maps.newHashMapWithExpectedSize(size);
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // Only start measuring table size after the first element inserted, to
1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // deal with empty-map optimization.
1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin      map1.put(0, null);
1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin      int initialBuckets = bucketsOf(map1);
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 1; i < size; i++) {
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        map1.put(i, null);
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEquals("table size after adding " + size + " elements",
1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin          initialBuckets, bucketsOf(map1));
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /*
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * Something slightly different happens when the entries are added all at
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * once; make sure that passes too.
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       */
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      HashMap<Integer, Void> map2 = Maps.newHashMapWithExpectedSize(size);
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map2.putAll(map1);
1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEquals("table size after adding " + size + "elements",
1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin          initialBuckets, bucketsOf(map2));
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("reflection")
1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static int bucketsOf(HashMap<?, ?> hashMap) throws Exception {
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Field tableField = HashMap.class.getDeclaredField("table");
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tableField.setAccessible(true);
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Object[] table = (Object[]) tableField.get(hashMap);
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return table.length;
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCapacityForLargeSizes() {
1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int[] largeExpectedSizes = new int[] {
1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Integer.MAX_VALUE / 2 - 1,
1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Integer.MAX_VALUE / 2,
1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Integer.MAX_VALUE / 2 + 1,
1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Integer.MAX_VALUE - 1,
1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Integer.MAX_VALUE};
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int expectedSize : largeExpectedSizes) {
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int capacity = Maps.capacity(expectedSize);
1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(
1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin          "capacity (" + capacity + ") must be >= expectedSize (" + expectedSize + ")",
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          capacity >= expectedSize);
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMap() {
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LinkedHashMap<Integer, Integer> map = Maps.newLinkedHashMap();
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("serial")
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMapWithInitialMap() {
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<String, String> map = new LinkedHashMap<String, String>() {{
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin      put("Hello", "World");
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin      put("first", "second");
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin      put("polygene", "lubricants");
1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin      put("alpha", "betical");
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }};
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LinkedHashMap<String, String> copy = Maps.newLinkedHashMap(map);
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<String, String>> iter = copy.entrySet().iterator();
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<String, String> entry = iter.next();
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("Hello", entry.getKey());
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("World", entry.getValue());
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("first", entry.getKey());
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("second", entry.getValue());
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("polygene", entry.getKey());
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("lubricants", entry.getValue());
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("alpha", entry.getKey());
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("betical", entry.getValue());
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(iter.hasNext());
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMapGeneralizesTypes() {
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new LinkedHashMap<String, Integer>();
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    HashMap<Object, Object> map
2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin        = Maps.<Object, Object>newLinkedHashMap(original);
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIdentityHashMap() {
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    IdentityHashMap<Integer, Integer> map = Maps.newIdentityHashMap();
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConcurrentMap() {
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ConcurrentMap<Integer, Integer> map = Maps.newConcurrentMap();
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMap() {
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Integer, Integer> map = Maps.newTreeMap();
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapDerived() {
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Derived, Integer> map = Maps.newTreeMap();
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new Derived("foo"), 1);
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new Derived("bar"), 2);
2473ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.keySet()).has().exactly(
2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new Derived("bar"), new Derived("foo")).inOrder();
2493ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.values()).has().exactly(2, 1).inOrder();
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapNonGeneric() {
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<LegacyComparable, Integer> map = Maps.newTreeMap();
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new LegacyComparable("foo"), 1);
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new LegacyComparable("bar"), 2);
2583ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.keySet()).has().exactly(
2590888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
2603ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.values()).has().exactly(2, 1).inOrder();
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapWithComparator() {
2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TreeMap<Integer, Integer> map = Maps.newTreeMap(SOME_COMPARATOR);
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(SOME_COMPARATOR, map.comparator());
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapWithInitialMap() {
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, Integer> map = Maps.newTreeMap();
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(5, 10);
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(3, 20);
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(1, 30);
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Integer, Integer> copy = Maps.newTreeMap(map);
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(copy, map);
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(copy.comparator(), map.comparator());
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2800888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public enum SomeEnum { SOME_INSTANCE }
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMap() {
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> map = Maps.newEnumMap(SomeEnum.class);
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(SomeEnum.SOME_INSTANCE, 0);
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.singletonMap(SomeEnum.SOME_INSTANCE, 0), map);
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapNullClass() {
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.<SomeEnum, Long>newEnumMap((Class<MapsTest.SomeEnum>) null);
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("no exception thrown");
2930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEnumMap() {
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put(SomeEnum.SOME_INSTANCE, 0);
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEmptyEnumMap() {
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNotSame(original, copy);
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialMap() {
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<SomeEnum, Integer> original = Maps.newHashMap();
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put(SomeEnum.SOME_INSTANCE, 0);
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEmptyMap() {
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<SomeEnum, Integer> original = Maps.newHashMap();
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.newEnumMap(original);
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Empty map must result in an IllegalArgumentException");
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException expected) {}
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3267dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToStringImplWithNullKeys() throws Exception {
3277dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> hashmap = Maps.newHashMap();
3287dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put("foo", "bar");
3297dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put(null, "baz");
3307dd252788645e940eada959bdde927426e2531c9Paul Duffin
3317dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
3327dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3337dd252788645e940eada959bdde927426e2531c9Paul Duffin
3347dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToStringImplWithNullValues() throws Exception {
3357dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> hashmap = Maps.newHashMap();
3367dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put("foo", "bar");
3377dd252788645e940eada959bdde927426e2531c9Paul Duffin    hashmap.put("baz", null);
3387dd252788645e940eada959bdde927426e2531c9Paul Duffin
3397dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
3407dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3417dd252788645e940eada959bdde927426e2531c9Paul Duffin
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("NullPointerTester")
3437dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testNullPointerExceptions() {
3447dd252788645e940eada959bdde927426e2531c9Paul Duffin    new NullPointerTester().testAllPublicStaticMethods(Maps.class);
3457dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3470888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Map<Integer, Integer> EMPTY
3480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      = Collections.emptyMap();
3490888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Map<Integer, Integer> SINGLETON
3500888a09821a98ac0680fad765217302858e70fa4Paul Duffin      = Collections.singletonMap(1, 2);
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEmptyEmpty() {
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, EMPTY);
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(diff.areEqual());
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnLeft());
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnRight());
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("equal", diff.toString());
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEmptySingleton() {
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, SINGLETON);
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnLeft());
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SINGLETON, diff.entriesOnlyOnRight());
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on right={1=2}", diff.toString());
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceSingletonEmpty() {
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(SINGLETON, EMPTY);
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SINGLETON, diff.entriesOnlyOnLeft());
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnRight());
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={1=2}", diff.toString());
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceTypical() {
3830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<Integer, String> left = ImmutableMap.of(
3840888a09821a98ac0680fad765217302858e70fa4Paul Duffin        1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
3850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<Integer, String> right = ImmutableMap.of(
3860888a09821a98ac0680fad765217302858e70fa4Paul Duffin        1, "a", 3, "f", 5, "g", 6, "z");
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff1 = Maps.difference(left, right);
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "z"), diff1.entriesOnlyOnRight());
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
3930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(ImmutableMap.of(3,
3940888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("c", "f"), 5,
3950888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("e", "g")),
3960888a09821a98ac0680fad765217302858e70fa4Paul Duffin        diff1.entriesDiffering());
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=z}: "
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(c, f), 5=(e, g)}", diff1.toString());
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff2 = Maps.difference(right, left);
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "z"), diff2.entriesOnlyOnLeft());
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff2.entriesInCommon());
4050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(ImmutableMap.of(3,
4060888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("f", "c"), 5,
4070888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("g", "e")),
4080888a09821a98ac0680fad765217302858e70fa4Paul Duffin        diff2.entriesDiffering());
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEquals() {
4140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<Integer, String> left = ImmutableMap.of(
4150888a09821a98ac0680fad765217302858e70fa4Paul Duffin        1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
4160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<Integer, String> right = ImmutableMap.of(
4170888a09821a98ac0680fad765217302858e70fa4Paul Duffin        1, "a", 3, "f", 5, "g", 6, "z");
4180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<Integer, String> right2 = ImmutableMap.of(
4190888a09821a98ac0680fad765217302858e70fa4Paul Duffin        1, "a", 3, "h", 5, "g", 6, "z");
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> original = Maps.difference(left, right);
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> same = Maps.difference(left, right);
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> reverse = Maps.difference(right, left);
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff2 = Maps.difference(left, right2);
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    new EqualsTester()
4260888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .addEqualityGroup(original, same)
4270888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .addEqualityGroup(reverse)
4280888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .addEqualityGroup(diff2)
4290888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .testEquals();
4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferencePredicateTypical() {
4330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<Integer, String> left = ImmutableMap.of(
4340888a09821a98ac0680fad765217302858e70fa4Paul Duffin        1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
4350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<Integer, String> right = ImmutableMap.of(
4360888a09821a98ac0680fad765217302858e70fa4Paul Duffin        1, "A", 3, "F", 5, "G", 6, "Z");
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // TODO(kevinb): replace with Ascii.caseInsensitiveEquivalence() when it
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // exists
4407dd252788645e940eada959bdde927426e2531c9Paul Duffin    Equivalence<String> caseInsensitiveEquivalence = Equivalence.equals().onResultOf(
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Function<String, String>() {
4420888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override public String apply(String input) {
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return input.toLowerCase();
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        });
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    MapDifference<Integer, String> diff1 = Maps.difference(left, right,
4480888a09821a98ac0680fad765217302858e70fa4Paul Duffin        caseInsensitiveEquivalence);
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "Z"), diff1.entriesOnlyOnRight());
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
4530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(ImmutableMap.of(3,
4540888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("c", "F"), 5,
4550888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("e", "G")),
4560888a09821a98ac0680fad765217302858e70fa4Paul Duffin        diff1.entriesDiffering());
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=Z}: "
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(c, F), 5=(e, G)}", diff1.toString());
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    MapDifference<Integer, String> diff2 = Maps.difference(right, left,
4610888a09821a98ac0680fad765217302858e70fa4Paul Duffin        caseInsensitiveEquivalence);
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "Z"), diff2.entriesOnlyOnLeft());
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "A"), diff2.entriesInCommon());
4660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(ImmutableMap.of(3,
4670888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("F", "c"), 5,
4680888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ValueDifferenceImpl.create("G", "e")),
4690888a09821a98ac0680fad765217302858e70fa4Paul Duffin        diff2.entriesDiffering());
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=Z}: only on right={2=b, 4=d}: "
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(F, c), 5=(G, e)}", diff2.toString());
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final SortedMap<Integer, Integer> SORTED_EMPTY = Maps.newTreeMap();
4750888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final SortedMap<Integer, Integer> SORTED_SINGLETON =
4760888a09821a98ac0680fad765217302858e70fa4Paul Duffin      ImmutableSortedMap.of(1, 2);
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceOfSortedMapIsSorted() {
4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Integer> map = SORTED_SINGLETON;
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> difference = Maps.difference(map, EMPTY);
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(difference instanceof SortedMapDifference);
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEmptyEmpty() {
4850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, Integer> diff =
4860888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(SORTED_EMPTY, SORTED_EMPTY);
4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(diff.areEqual());
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("equal", diff.toString());
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEmptySingleton() {
4960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, Integer> diff =
4970888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(SORTED_EMPTY, SORTED_SINGLETON);
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnRight());
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on right={1=2}", diff.toString());
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceSingletonEmpty() {
5070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, Integer> diff =
5080888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(SORTED_SINGLETON, SORTED_EMPTY);
5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnLeft());
5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={1=2}", diff.toString());
5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceTypical() {
5180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<Integer, String> left =
5190888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.<Integer, String>reverseOrder()
5200888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .put(1, "a").put(2, "b").put(3, "c").put(4, "d").put(5, "e")
5210888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .build();
5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5230888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<Integer, String> right =
5240888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, String> diff1 =
5270888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(left, right);
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
5293ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesOnlyOnLeft().entrySet()).has().exactly(
5300888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder();
5313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesOnlyOnRight().entrySet()).has().item(
5320888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(6, "z"));
5333ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesInCommon().entrySet()).has().item(
5340888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(1, "a"));
5353ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesDiffering().entrySet()).has().exactly(
5360888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")),
5370888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder();
5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={4=d, 2=b}: only on right={6=z}: "
5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={5=(e, g), 3=(c, f)}", diff1.toString());
5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, String> diff2 =
5420888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(right, left);
5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
5443ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff2.entriesOnlyOnLeft().entrySet()).has().item(
5450888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(6, "z"));
5463ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff2.entriesOnlyOnRight().entrySet()).has().exactly(
5470888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
5483ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesInCommon().entrySet()).has().item(
5490888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(1, "a"));
5500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(ImmutableMap.of(
5510888a09821a98ac0680fad765217302858e70fa4Paul Duffin            3, ValueDifferenceImpl.create("f", "c"),
5520888a09821a98ac0680fad765217302858e70fa4Paul Duffin            5, ValueDifferenceImpl.create("g", "e")),
5530888a09821a98ac0680fad765217302858e70fa4Paul Duffin        diff2.entriesDiffering());
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceImmutable() {
5590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<Integer, String> left = Maps.newTreeMap(
5600888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"));
5610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<Integer, String> right =
5620888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z"));
5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5640888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, String> diff1 =
5650888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(left, right);
5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    left.put(6, "z");
5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
5683ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesOnlyOnLeft().entrySet()).has().exactly(
5690888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
5703ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesOnlyOnRight().entrySet()).has().item(
5710888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(6, "z"));
5723ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesInCommon().entrySet()).has().item(
5730888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(1, "a"));
5743ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(diff1.entriesDiffering().entrySet()).has().exactly(
5750888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")),
5760888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder();
5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesInCommon().put(7, "x");
5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
5810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesOnlyOnLeft().put(7, "x");
5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
5860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesOnlyOnRight().put(7, "x");
5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
5910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEquals() {
5950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<Integer, String> left =
5960888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
5970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<Integer, String> right =
5980888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
5990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<Integer, String> right2 =
6000888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of(1, "a", 3, "h", 5, "g", 6, "z");
6010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, String> original =
6020888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(left, right);
6030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, String> same =
6040888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(left, right);
6050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, String> reverse =
6060888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(right, left);
6070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMapDifference<Integer, String> diff2 =
6080888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.difference(left, right2);
6090888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    new EqualsTester()
6110888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .addEqualityGroup(original, same)
6120888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .addEqualityGroup(reverse)
6130888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .addEqualityGroup(diff2)
6140888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .testEquals();
6150888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6170888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Function<String, Integer> LENGTH_FUNCTION =
6180888a09821a98ac0680fad765217302858e70fa4Paul Duffin      new Function<String, Integer>() {
6190888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override
6200888a09821a98ac0680fad765217302858e70fa4Paul Duffin        public Integer apply(String input) {
6210888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return input.length();
6220888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
6230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      };
6247dd252788645e940eada959bdde927426e2531c9Paul Duffin
6257dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMap() {
6267dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = ImmutableSet.of("one", "two", "three");
6277dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6287dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6297dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
6307dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
6313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
6320888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("one", 3),
6330888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("two", 3),
6340888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5)).inOrder();
6357dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6367dd252788645e940eada959bdde927426e2531c9Paul Duffin
6377dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapReadsThrough() {
6387dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = Sets.newLinkedHashSet();
6397dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6407dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6417dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6427dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("four"));
6437dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.add("four");
6447dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5, "four", 4), map);
6457dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
6467dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6477dd252788645e940eada959bdde927426e2531c9Paul Duffin
6487dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapWritesThrough() {
6497dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = Sets.newLinkedHashSet();
6507dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6517dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6527dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6537dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
6543ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(strings).has().exactly("one", "three").inOrder();
6557dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6567dd252788645e940eada959bdde927426e2531c9Paul Duffin
6577dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapEmpty() {
6587dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> strings = ImmutableSet.of();
6597dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6603ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).isEmpty();
6617dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertTrue(map.isEmpty());
6627dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6650888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static class NonNavigableSortedSet
6660888a09821a98ac0680fad765217302858e70fa4Paul Duffin      extends ForwardingSortedSet<String> {
6677dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final SortedSet<String> delegate = Sets.newTreeSet();
6687dd252788645e940eada959bdde927426e2531c9Paul Duffin
669dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    @Override
6707dd252788645e940eada959bdde927426e2531c9Paul Duffin    protected SortedSet<String> delegate() {
6717dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate;
672dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    }
673dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin  }
674dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
6757dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapReturnsSortedMapForSortedSetInput() {
6767dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<String> set = new NonNavigableSortedSet();
6777dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertTrue(Maps.asMap(set, Functions.identity()) instanceof SortedMap);
6787dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6797dd252788645e940eada959bdde927426e2531c9Paul Duffin
6807dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSorted() {
6817dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
6827dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6837dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6847dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6857dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
6867dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
6873ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
6880888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("one", 3),
6890888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5),
6900888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("two", 3)).inOrder();
6913ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.tailMap("onea").entrySet()).has().exactly(
6920888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5),
6930888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("two", 3)).inOrder();
6943ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.subMap("one", "two").entrySet()).has().exactly(
6950888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("one", 3),
6960888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5)).inOrder();
6977dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
698dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
6997dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedReadsThrough() {
7007dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
7017dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
7027dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
7037dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.comparator());
7047dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
7057dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("four"));
7067dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.add("four");
7070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(
7080888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
7090888a09821a98ac0680fad765217302858e70fa4Paul Duffin        map);
7107dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
7117dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> headMap = map.headMap("two");
7120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(
7130888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
7140888a09821a98ac0680fad765217302858e70fa4Paul Duffin        headMap);
7157dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.add("five");
7167dd252788645e940eada959bdde927426e2531c9Paul Duffin    strings.remove("one");
7170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(
7180888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
7190888a09821a98ac0680fad765217302858e70fa4Paul Duffin        headMap);
7203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
7210888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("five", 4),
7220888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("four", 4),
7230888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5),
7240888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("two", 3)).inOrder();
7257dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7267dd252788645e940eada959bdde927426e2531c9Paul Duffin
7277dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedWritesThrough() {
7287dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
7297dd252788645e940eada959bdde927426e2531c9Paul Duffin    Collections.addAll(strings, "one", "two", "three");
7307dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
7317dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
7327dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
7333ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(strings).has().exactly("one", "three").inOrder();
7347dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7357dd252788645e940eada959bdde927426e2531c9Paul Duffin
7367dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedSubViewKeySetsDoNotSupportAdd() {
7370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(
7380888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new NonNavigableSortedSet(), LENGTH_FUNCTION);
7397dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
7407dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.subMap("a", "z").keySet().add("a");
7417dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
7420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
7430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
7447dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
7457dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.tailMap("a").keySet().add("a");
7467dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
7470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
7480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
7497dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
7507dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.headMap("r").keySet().add("a");
7517dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
7520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
7530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
7547dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
7557dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.headMap("r").tailMap("m").keySet().add("a");
7567dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
7570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
7580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
7597dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7607dd252788645e940eada959bdde927426e2531c9Paul Duffin
7617dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testAsMapSortedEmpty() {
7627dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
7637dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
7643ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).isEmpty();
7653ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertTrue(map.isEmpty());
7663ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertNull(map.get("five"));
7673ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
7683ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
7693ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
7703ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testAsMapReturnsNavigableMapForNavigableSetInput() {
7713ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Set<String> set = Sets.newTreeSet();
7723ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertTrue(Maps.asMap(set, Functions.identity()) instanceof NavigableMap);
7733ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
7743ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
7753ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
7763ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testAsMapNavigable() {
7773ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableSet<String> strings =
7783ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        Sets.newTreeSet(asList("one", "two", "three"));
7793ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
7803ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
7813ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
7823ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertNull(map.get("five"));
7833ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
7843ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("one", 3),
7853ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("three", 5),
7863ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("two", 3)).inOrder();
7873ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.tailMap("onea").entrySet()).has().exactly(
7883ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("three", 5),
7893ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("two", 3)).inOrder();
7903ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.subMap("one", "two").entrySet()).has().exactly(
7913ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("one", 3),
7923ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("three", 5)).inOrder();
7933ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
7943ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableSortedMap.of("two", 3, "three", 5),
7953ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        map.tailMap("three", true));
7963ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "three", 5),
7973ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        map.headMap("two", false));
7983ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableSortedMap.of("three", 5),
7993ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        map.subMap("one", false, "tr", true));
8003ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8013ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("three", map.higherKey("one"));
8023ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("three", map.higherKey("r"));
8033ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("three", map.ceilingKey("r"));
8043ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("one", map.ceilingKey("one"));
8053ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(mapEntry("three", 5), map.higherEntry("one"));
8063ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(mapEntry("one", 3), map.ceilingEntry("one"));
8073ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("one", map.lowerKey("three"));
8083ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("one", map.lowerKey("r"));
8093ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("one", map.floorKey("r"));
8103ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("three", map.floorKey("three"));
8113ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8123ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.descendingMap().entrySet()).has().exactly(
8133ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("two", 3),
8143ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("three", 5),
8153ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("one", 3)).inOrder();
8163ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(map.headMap("three", true),
8173ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        map.descendingMap().tailMap("three", true));
8183ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.tailMap("three", false).entrySet()).has().item(
8193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("two", 3));
8203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertNull(map.tailMap("three", true).lowerEntry("three"));
8213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.headMap("two", false).values()).has().exactly(3, 5).inOrder();
8223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.headMap("two", false).descendingMap().values())
8233ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        .has().exactly(5, 3).inOrder();
8243ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.descendingKeySet()).has().exactly(
8253ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        "two", "three", "one").inOrder();
8263ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8273ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(mapEntry("one", 3), map.pollFirstEntry());
8283ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(mapEntry("two", 3), map.pollLastEntry());
8293ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(1, map.size());
8303ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
8313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8323ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
8333ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testAsMapNavigableReadsThrough() {
8343ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableSet<String> strings = Sets.newTreeSet();
8353ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Collections.addAll(strings, "one", "two", "three");
8363ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
8373ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertNull(map.comparator());
8383ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
8393ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertNull(map.get("four"));
8403ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    strings.add("four");
8413ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(
8423ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
8433ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        map);
8443ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
8453ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    SortedMap<String, Integer> headMap = map.headMap("two");
8463ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(
8473ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
8483ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        headMap);
8493ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    strings.add("five");
8503ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    strings.remove("one");
8513ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(
8523ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
8533ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        headMap);
8543ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
8553ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("five", 4),
8563ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("four", 4),
8573ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("three", 5),
8583ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("two", 3)).inOrder();
8593ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8603ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> tailMap = map.tailMap("s", true);
8613ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> subMap = map.subMap("a", true, "t", false);
8623ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8633ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    strings.add("six");
8643ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    strings.remove("two");
8653ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(tailMap.entrySet()).has().exactly(
8663ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("six", 3),
8673ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("three", 5)).inOrder();
8683ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(subMap.entrySet()).has().exactly(
8693ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("five", 4),
8703ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("four", 4),
8713ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        mapEntry("six", 3)).inOrder();
8723ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
8733ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8743ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
8753ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testAsMapNavigableWritesThrough() {
8763ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableSet<String> strings = Sets.newTreeSet();
8773ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Collections.addAll(strings, "one", "two", "three");
8783ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
8793ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
8803ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
8813ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(strings).has().exactly("one", "three").inOrder();
8823ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(mapEntry("three", 5),
8833ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        map.subMap("one", false, "zzz", true).pollLastEntry());
8843ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(strings).has().item("one");
8853ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
8863ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
8873ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
8883ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testAsMapNavigableSubViewKeySetsDoNotSupportAdd() {
8893ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(
8903ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        Sets.<String>newTreeSet(), LENGTH_FUNCTION);
8913ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
8923ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      map.descendingKeySet().add("a");
8933ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail();
8943ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
8953ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
8963ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
8973ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      map.subMap("a", true, "z", false).keySet().add("a");
8983ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail();
8993ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
9003ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
9013ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
9023ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      map.tailMap("a", true).keySet().add("a");
9033ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail();
9043ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
9053ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
9063ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
9073ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      map.headMap("r", true).keySet().add("a");
9083ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail();
9093ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
9103ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
9113ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
9123ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      map.headMap("r", false).tailMap("m", true).keySet().add("a");
9133ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail();
9143ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
9153ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
9163ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
9173ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
9183ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
9193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testAsMapNavigableEmpty() {
9203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableSet<String> strings = ImmutableSortedSet.of();
9213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
9223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).isEmpty();
9237dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertTrue(map.isEmpty());
9247dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertNull(map.get("five"));
9257dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9267dd252788645e940eada959bdde927426e2531c9Paul Duffin
9277dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMap() {
9287dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three");
9297dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
9307dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
9313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
9320888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("one", 3),
9330888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("two", 3),
9340888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5)).inOrder();
9357dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9367dd252788645e940eada959bdde927426e2531c9Paul Duffin
9377dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapIterator() {
9387dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterator<String> strings = ImmutableList.of("one", "two", "three").iterator();
9397dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
9407dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
9413ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
9420888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("one", 3),
9430888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("two", 3),
9440888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5)).inOrder();
9457dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9467dd252788645e940eada959bdde927426e2531c9Paul Duffin
9477dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapWithDuplicateKeys() {
9487dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three", "two", "one");
9497dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
9507dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
9513ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(map.entrySet()).has().exactly(
9520888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("one", 3),
9530888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("two", 3),
9540888a09821a98ac0680fad765217302858e70fa4Paul Duffin        mapEntry("three", 5)).inOrder();
9557dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9567dd252788645e940eada959bdde927426e2531c9Paul Duffin
9577dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapWithNullKeys() {
9587dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = Arrays.asList("one", null, "three");
9597dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
9607dd252788645e940eada959bdde927426e2531c9Paul Duffin      Maps.toMap(strings, Functions.constant("foo"));
9617dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
9620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
9630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
9647dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9657dd252788645e940eada959bdde927426e2531c9Paul Duffin
9667dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testToMapWithNullValues() {
9677dd252788645e940eada959bdde927426e2531c9Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three");
9687dd252788645e940eada959bdde927426e2531c9Paul Duffin    try {
9697dd252788645e940eada959bdde927426e2531c9Paul Duffin      Maps.toMap(strings, Functions.constant(null));
9707dd252788645e940eada959bdde927426e2531c9Paul Duffin      fail();
9710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
9720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
9737dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9747dd252788645e940eada959bdde927426e2531c9Paul Duffin
9750888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final BiMap<Integer, String> INT_TO_STRING_MAP =
9760888a09821a98ac0680fad765217302858e70fa4Paul Duffin      new ImmutableBiMap.Builder<Integer, String>()
9770888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .put(1, "one")
9780888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .put(2, "two")
9790888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .put(3, "three")
9800888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .build();
9817dd252788645e940eada959bdde927426e2531c9Paul Duffin
9827dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testUniqueIndexCollection() {
9830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableMap<Integer, String> outputMap =
9840888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.uniqueIndex(INT_TO_STRING_MAP.values(),
9850888a09821a98ac0680fad765217302858e70fa4Paul Duffin            Functions.forMap(INT_TO_STRING_MAP.inverse()));
986dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    assertEquals(INT_TO_STRING_MAP, outputMap);
987dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin  }
988dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
9897dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testUniqueIndexIterable() {
9900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableMap<Integer, String> outputMap =
9910888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.uniqueIndex(new Iterable<String>() {
9920888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override
9930888a09821a98ac0680fad765217302858e70fa4Paul Duffin          public Iterator<String> iterator() {
9940888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return INT_TO_STRING_MAP.values().iterator();
9950888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
9960888a09821a98ac0680fad765217302858e70fa4Paul Duffin        },
9970888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Functions.forMap(INT_TO_STRING_MAP.inverse()));
9987dd252788645e940eada959bdde927426e2531c9Paul Duffin    assertEquals(INT_TO_STRING_MAP, outputMap);
9997dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
10007dd252788645e940eada959bdde927426e2531c9Paul Duffin
10011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexIterator() {
10020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableMap<Integer, String> outputMap =
10030888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Maps.uniqueIndex(INT_TO_STRING_MAP.values().iterator(),
10040888a09821a98ac0680fad765217302858e70fa4Paul Duffin            Functions.forMap(INT_TO_STRING_MAP.inverse()));
10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(INT_TO_STRING_MAP, outputMap);
10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Can't create the map if more than one value maps to the same key. */
10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexDuplicates() {
10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(ImmutableSet.of("one", "uno"), Functions.constant(1));
10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
10130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IllegalArgumentException expected) {
10140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Null values are not allowed. */
10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexNullValue() {
10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<String> listWithNull = Lists.newArrayList((String) null);
10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(listWithNull, Functions.constant(1));
10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
10230888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
10240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Null keys aren't allowed either. */
10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexNullKey() {
10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<String> oneStringList = Lists.newArrayList("foo");
10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(oneStringList, Functions.constant(null));
10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
10330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
10340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
10380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @SuppressWarnings("deprecation") // StringBufferInputStream
10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromProperties() throws IOException {
10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties testProp = new Properties();
10411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> result = Maps.fromProperties(testProp);
10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.isEmpty());
10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp.setProperty("first", "true");
10451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
10481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(1, result.size());
10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp.setProperty("second", "null");
10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
10531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("null", result.get("second"));
10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(2, result.size());
10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Now test values loaded from a stream.
10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String props = "test\n second = 2\n Third item :   a short  phrase   ";
10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10593ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    testProp.load(new StringReader(props));
10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(4, result.size());
10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
10641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("", result.get("test"));
10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("2", result.get("second"));
10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("item :   a short  phrase   ", result.get("Third"));
10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(result.containsKey("not here"));
10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test loading system properties
10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(System.getProperties());
10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.containsKey("java.version"));
10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test that defaults work, too.
10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp = new Properties(System.getProperties());
10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String override = "test\njava.version : hidden";
10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10773ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    testProp.load(new StringReader(override));
10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.size() > 2);
10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("", result.get("test"));
10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("hidden", result.get("java.version"));
10830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertNotSame(System.getProperty("java.version"),
10840888a09821a98ac0680fad765217302858e70fa4Paul Duffin                  result.get("java.version"));
10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
10880888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @SuppressWarnings("serial") // never serialized
10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromPropertiesNullKey() {
10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties properties = new Properties() {
10910888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override public Enumeration<?> propertyNames() {
10920888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return Iterators.asEnumeration(
10930888a09821a98ac0680fad765217302858e70fa4Paul Duffin            Arrays.asList(null, "first", "second").iterator());
10941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    properties.setProperty("first", "true");
10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    properties.setProperty("second", "null");
10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.fromProperties(properties);
11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {}
11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
11060888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @SuppressWarnings("serial") // never serialized
11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromPropertiesNonStringKeys() {
11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties properties = new Properties() {
11090888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override public Enumeration<?> propertyNames() {
11100888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return Iterators.asEnumeration(
11110888a09821a98ac0680fad765217302858e70fa4Paul Duffin            Arrays.<Object>asList(Integer.valueOf(123), "first").iterator());
11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.fromProperties(properties);
11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ClassCastException expected) {}
11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11210888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_nominal() throws Exception {
11220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
11230888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "one", 1,
11240888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "two", 2);
11250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Converter<String, Integer> converter = Maps.asConverter(biMap);
11260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (Entry<String, Integer> entry : biMap.entrySet()) {
11270888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertSame(entry.getValue(), converter.convert(entry.getKey()));
11280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
11290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
11307dd252788645e940eada959bdde927426e2531c9Paul Duffin
11310888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_inverse() throws Exception {
11320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
11330888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "one", 1,
11340888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "two", 2);
11350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Converter<String, Integer> converter = Maps.asConverter(biMap);
11360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (Entry<String, Integer> entry : biMap.entrySet()) {
11370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertSame(entry.getKey(), converter.reverse().convert(entry.getValue()));
11380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
11390888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
11407dd252788645e940eada959bdde927426e2531c9Paul Duffin
11410888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_noMapping() throws Exception {
11420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
11430888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "one", 1,
11440888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "two", 2);
11450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Converter<String, Integer> converter = Maps.asConverter(biMap);
11460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
11470888a09821a98ac0680fad765217302858e70fa4Paul Duffin      converter.convert("three");
11480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
11490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IllegalArgumentException expected) {
11500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
11510888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
11520888a09821a98ac0680fad765217302858e70fa4Paul Duffin
11530888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_nullConversions() throws Exception {
11540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
11550888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "one", 1,
11560888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "two", 2);
11570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Converter<String, Integer> converter = Maps.asConverter(biMap);
11580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertNull(converter.convert(null));
11590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertNull(converter.reverse().convert(null));
11600888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
11610888a09821a98ac0680fad765217302858e70fa4Paul Duffin
11620888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_isAView() throws Exception {
11630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    BiMap<String, Integer> biMap = HashBiMap.create();
11640888a09821a98ac0680fad765217302858e70fa4Paul Duffin    biMap.put("one", 1);
11650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    biMap.put("two", 2);
11660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Converter<String, Integer> converter = Maps.asConverter(biMap);
11670888a09821a98ac0680fad765217302858e70fa4Paul Duffin
11680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(1, converter.convert("one"));
11690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(2, converter.convert("two"));
11700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
11710888a09821a98ac0680fad765217302858e70fa4Paul Duffin      converter.convert("three");
11720888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
11730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IllegalArgumentException expected) {
11740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
11750888a09821a98ac0680fad765217302858e70fa4Paul Duffin
11760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    biMap.put("three", 3);
11770888a09821a98ac0680fad765217302858e70fa4Paul Duffin
11780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(1, converter.convert("one"));
11790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(2, converter.convert("two"));
11800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(3, converter.convert("three"));
11810888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
11820888a09821a98ac0680fad765217302858e70fa4Paul Duffin
11830888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_withNullMapping() throws Exception {
11840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    BiMap<String, Integer> biMap = HashBiMap.create();
11850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    biMap.put("one", 1);
11860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    biMap.put("two", 2);
11870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    biMap.put("three", null);
11880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
11890888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Maps.asConverter(biMap).convert("three");
11900888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
11910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IllegalArgumentException expected) {
11920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
11930888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
11940888a09821a98ac0680fad765217302858e70fa4Paul Duffin
11950888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_toString() {
11960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
11970888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "one", 1,
11980888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "two", 2);
11990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Converter<String, Integer> converter = Maps.asConverter(biMap);
12000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("Maps.asConverter({one=1, two=2})", converter.toString());
12010888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
12020888a09821a98ac0680fad765217302858e70fa4Paul Duffin
12030888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAsConverter_serialization() {
12040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of(
12050888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "one", 1,
12060888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "two", 2);
12070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Converter<String, Integer> converter = Maps.asConverter(biMap);
12080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SerializableTester.reserializeAndAssert(converter);
12091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUnmodifiableBiMap() {
12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<Integer, String> mod = HashBiMap.create();
12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(1, "one");
12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(2, "two");
12151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(3, "three");
12161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<Number, String> unmod = Maps.<Number, String>unmodifiableBiMap(mod);
12181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* No aliasing on inverse operations. */
12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(unmod.inverse(), unmod.inverse());
12211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(unmod, unmod.inverse().inverse());
12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* Unmodifiable is a view. */
12241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(4, "four");
12251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(true, unmod.get(4).equals("four"));
12261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(true, unmod.inverse().get("four").equals(4));
12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* UnsupportedOperationException on direct modifications. */
12291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.put(4, "four");
12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.forcePut(4, "four");
12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.putAll(Collections.singletonMap(4, "four"));
12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* UnsupportedOperationException on indirect modifications. */
12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Number> inverse = unmod.inverse();
12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.put("four", 4);
12461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.forcePut("four", 4);
12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.putAll(Collections.singletonMap("four", 4));
12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<String> values = unmod.values();
12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      values.remove("four");
12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Map.Entry<Number, String>> entries = unmod.entrySet();
12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<Number, String> entry = entries.iterator().next();
12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entry.setValue("four");
12651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
12680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map.Entry<Integer, String> entry2
12690888a09821a98ac0680fad765217302858e70fa4Paul Duffin        = (Map.Entry<Integer, String>) entries.toArray()[0];
12701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entry2.setValue("four");
12721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testImmutableEntry() {
12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<String, Integer> e = Maps.immutableEntry("foo", 1);
12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("foo", e.getKey());
12791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(1, (int) e.getValue());
12801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      e.setValue(2);
12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("foo=1", e.toString());
12851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(101575, e.hashCode());
12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testImmutableEntryNull() {
12890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map.Entry<String, Integer> e
12900888a09821a98ac0680fad765217302858e70fa4Paul Duffin        = Maps.immutableEntry((String) null, (Integer) null);
12911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(e.getKey());
12921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(e.getValue());
12931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      e.setValue(null);
12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("null=null", e.toString());
12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(0, e.hashCode());
12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** See {@link SynchronizedBiMapTest} for more tests. */
13021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSynchronizedBiMap() {
13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Integer> bimap = HashBiMap.create();
13041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    bimap.put("one", 1);
13051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Integer> sync = Maps.synchronizedBiMap(bimap);
13061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    bimap.put("two", 2);
13071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    sync.put("three", 3);
13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSet.of(1, 2, 3), bimap.inverse().keySet());
13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSet.of(1, 2, 3), sync.inverse().keySet());
13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13120888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Predicate<String> NOT_LENGTH_3
13130888a09821a98ac0680fad765217302858e70fa4Paul Duffin      = new Predicate<String>() {
13140888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override
13150888a09821a98ac0680fad765217302858e70fa4Paul Duffin        public boolean apply(String input) {
13160888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return input == null || input.length() != 3;
13170888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
13180888a09821a98ac0680fad765217302858e70fa4Paul Duffin      };
13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13200888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Predicate<Integer> EVEN
13210888a09821a98ac0680fad765217302858e70fa4Paul Duffin      = new Predicate<Integer>() {
13220888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override
13230888a09821a98ac0680fad765217302858e70fa4Paul Duffin        public boolean apply(Integer input) {
13240888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return input == null || input % 2 == 0;
13250888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
13260888a09821a98ac0680fad765217302858e70fa4Paul Duffin      };
13271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13280888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Predicate<Entry<String, Integer>> CORRECT_LENGTH
13290888a09821a98ac0680fad765217302858e70fa4Paul Duffin      = new Predicate<Entry<String, Integer>>() {
13300888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override
13310888a09821a98ac0680fad765217302858e70fa4Paul Duffin        public boolean apply(Entry<String, Integer> input) {
13320888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return input.getKey().length() == input.getValue();
13330888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
13340888a09821a98ac0680fad765217302858e70fa4Paul Duffin      };
13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13367dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Function<Integer, Double> SQRT_FUNCTION = new Function<Integer, Double>() {
13370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
13380888a09821a98ac0680fad765217302858e70fa4Paul Duffin      public Double apply(Integer in) {
13390888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return Math.sqrt(in);
13400888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
13410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    };
13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13437dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class FilteredMapTest extends TestCase {
13447dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Integer> createUnfiltered() {
13457dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Maps.newHashMap();
13467dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
13473c77433663281544363151bf284b0240dfd22a42Paul Duffin
13487dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredKeysIllegalPut() {
13497dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13507dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
13517dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 1);
13527dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("b", 2);
13537dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
13543c77433663281544363151bf284b0240dfd22a42Paul Duffin
13557dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
13567dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.put("yyy", 3);
13577dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
13587dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
13597dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
13603c77433663281544363151bf284b0240dfd22a42Paul Duffin
13617dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredKeysIllegalPutAll() {
13627dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13637dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
13647dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 1);
13657dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("b", 2);
13667dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
13673c77433663281544363151bf284b0240dfd22a42Paul Duffin
13687dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
13697dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
13707dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
13717dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
13723c77433663281544363151bf284b0240dfd22a42Paul Duffin
13737dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
13747dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
13753c77433663281544363151bf284b0240dfd22a42Paul Duffin
13767dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredKeysFilteredReflectsBackingChanges() {
13777dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13787dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
13797dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("two", 2);
13807dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("three", 3);
13817dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("four", 4);
13827dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
13837dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
13847dd252788645e940eada959bdde927426e2531c9Paul Duffin
13857dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.remove("three");
13867dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
13877dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("four", 4), filtered);
13887dd252788645e940eada959bdde927426e2531c9Paul Duffin
13897dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.clear();
13907dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of(), unfiltered);
13917dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of(), filtered);
13927dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
13931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13947dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesIllegalPut() {
13957dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13967dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
13977dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 2);
13987dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("b", 4);
13997dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("c", 5);
14007dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
14013c77433663281544363151bf284b0240dfd22a42Paul Duffin
14027dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
14037dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.put("yyy", 3);
14047dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
14057dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
14067dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
14077dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
14081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14097dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesIllegalPutAll() {
14107dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14117dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
14127dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 2);
14137dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("b", 4);
14147dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("c", 5);
14157dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
14163c77433663281544363151bf284b0240dfd22a42Paul Duffin
14177dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
14187dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
14197dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
14207dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
14217dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
14227dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
14233c77433663281544363151bf284b0240dfd22a42Paul Duffin
14247dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesIllegalSetValue() {
14257dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14267dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
14277dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("a", 2);
14287dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("b", 4);
14297dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
14303c77433663281544363151bf284b0240dfd22a42Paul Duffin
14317dd252788645e940eada959bdde927426e2531c9Paul Duffin      Entry<String, Integer> entry = filtered.entrySet().iterator().next();
14327dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
14337dd252788645e940eada959bdde927426e2531c9Paul Duffin        entry.setValue(5);
14347dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
14357dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
14363c77433663281544363151bf284b0240dfd22a42Paul Duffin
14377dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
14387dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
14393c77433663281544363151bf284b0240dfd22a42Paul Duffin
14407dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredValuesClear() {
14417dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14427dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("one", 1);
14437dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("two", 2);
14447dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("three", 3);
14457dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("four", 4);
14467dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
14470888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
14480888a09821a98ac0680fad765217302858e70fa4Paul Duffin          unfiltered);
14497dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
14507dd252788645e940eada959bdde927426e2531c9Paul Duffin
14517dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.clear();
14527dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
14537dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(filtered.isEmpty());
14547dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
14557dd252788645e940eada959bdde927426e2531c9Paul Duffin
14567dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesIllegalPut() {
14577dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14587dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
14597dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
14607dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
14610888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Map<String, Integer> filtered
14620888a09821a98ac0680fad765217302858e70fa4Paul Duffin          = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
14637dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
14647dd252788645e940eada959bdde927426e2531c9Paul Duffin
14657dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("chicken", 7);
14667dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
14673c77433663281544363151bf284b0240dfd22a42Paul Duffin
14687dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
14697dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.put("cow", 7);
14707dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
14717dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
14727dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
14737dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
14747dd252788645e940eada959bdde927426e2531c9Paul Duffin
14757dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesIllegalPutAll() {
14767dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14777dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
14787dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
14797dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
14800888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Map<String, Integer> filtered
14810888a09821a98ac0680fad765217302858e70fa4Paul Duffin          = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
14827dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
14837dd252788645e940eada959bdde927426e2531c9Paul Duffin
14847dd252788645e940eada959bdde927426e2531c9Paul Duffin      filtered.put("chicken", 7);
14857dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
14867dd252788645e940eada959bdde927426e2531c9Paul Duffin
14877dd252788645e940eada959bdde927426e2531c9Paul Duffin      try {
14887dd252788645e940eada959bdde927426e2531c9Paul Duffin        filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
14897dd252788645e940eada959bdde927426e2531c9Paul Duffin        fail();
14907dd252788645e940eada959bdde927426e2531c9Paul Duffin      } catch (IllegalArgumentException expected) {}
14917dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
14927dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
14937dd252788645e940eada959bdde927426e2531c9Paul Duffin
14947dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesObjectPredicate() {
14957dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14967dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
14977dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
14987dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
14997dd252788645e940eada959bdde927426e2531c9Paul Duffin      Predicate<Object> predicate = Predicates.alwaysFalse();
15000888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Map<String, Integer> filtered
15010888a09821a98ac0680fad765217302858e70fa4Paul Duffin          = Maps.filterEntries(unfiltered, predicate);
15027dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertTrue(filtered.isEmpty());
15037dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15047dd252788645e940eada959bdde927426e2531c9Paul Duffin
15057dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilteredEntriesWildCardEntryPredicate() {
15067dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
15077dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
15087dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 2);
15097dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("horse", 5);
15107dd252788645e940eada959bdde927426e2531c9Paul Duffin      Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
15117dd252788645e940eada959bdde927426e2531c9Paul Duffin        @Override
15127dd252788645e940eada959bdde927426e2531c9Paul Duffin        public boolean apply(Entry<?, ?> input) {
15130888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return "cat".equals(input.getKey())
15140888a09821a98ac0680fad765217302858e70fa4Paul Duffin              || Integer.valueOf(2) == input.getValue();
15157dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
15167dd252788645e940eada959bdde927426e2531c9Paul Duffin      };
15170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Map<String, Integer> filtered
15180888a09821a98ac0680fad765217302858e70fa4Paul Duffin          = Maps.filterEntries(unfiltered, predicate);
15197dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
15207dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1521dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin  }
15223c77433663281544363151bf284b0240dfd22a42Paul Duffin
15237dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class FilteredSortedMapTest extends FilteredMapTest {
15247dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
15257dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, Integer> createUnfiltered() {
15267dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Maps.newTreeMap();
15277dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15287dd252788645e940eada959bdde927426e2531c9Paul Duffin
15297dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterKeysIdentifiesSortedMap() {
15307dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
15310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
15320888a09821a98ac0680fad765217302858e70fa4Paul Duffin          instanceof SortedMap);
15337dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15347dd252788645e940eada959bdde927426e2531c9Paul Duffin
15357dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterValuesIdentifiesSortedMap() {
15367dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
15370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
15380888a09821a98ac0680fad765217302858e70fa4Paul Duffin          instanceof SortedMap);
15397dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15407dd252788645e940eada959bdde927426e2531c9Paul Duffin
15417dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterEntriesIdentifiesSortedMap() {
15427dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
15430888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
15440888a09821a98ac0680fad765217302858e70fa4Paul Duffin          instanceof SortedMap);
15457dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15467dd252788645e940eada959bdde927426e2531c9Paul Duffin
15477dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFirstAndLastKeyFilteredMap() {
15487dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> unfiltered = createUnfiltered();
15497dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("apple", 2);
15507dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("banana", 6);
15517dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 3);
15527dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 5);
15537dd252788645e940eada959bdde927426e2531c9Paul Duffin
15547dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
15557dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals("banana", filtered.firstKey());
15567dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals("cat", filtered.lastKey());
15577dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15587dd252788645e940eada959bdde927426e2531c9Paul Duffin
15597dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testHeadSubTailMap_FilteredMap() {
15607dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> unfiltered = createUnfiltered();
15617dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("apple", 2);
15627dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("banana", 6);
15637dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("cat", 4);
15647dd252788645e940eada959bdde927426e2531c9Paul Duffin      unfiltered.put("dog", 3);
15657dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
15667dd252788645e940eada959bdde927426e2531c9Paul Duffin
15677dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6), filtered.headMap("dog"));
15687dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of(), filtered.headMap("banana"));
15697dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.headMap("emu"));
15707dd252788645e940eada959bdde927426e2531c9Paul Duffin
15717dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6), filtered.subMap("banana", "dog"));
15727dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("dog", 3), filtered.subMap("cat", "emu"));
15733c77433663281544363151bf284b0240dfd22a42Paul Duffin
15747dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("dog", 3), filtered.tailMap("cat"));
15757dd252788645e940eada959bdde927426e2531c9Paul Duffin      assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.tailMap("banana"));
15767dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15797dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class FilteredBiMapTest extends FilteredMapTest {
15807dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
15817dd252788645e940eada959bdde927426e2531c9Paul Duffin    BiMap<String, Integer> createUnfiltered() {
15827dd252788645e940eada959bdde927426e2531c9Paul Duffin      return HashBiMap.create();
15837dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15857dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterKeysIdentifiesBiMap() {
15867dd252788645e940eada959bdde927426e2531c9Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
15870888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
15880888a09821a98ac0680fad765217302858e70fa4Paul Duffin          instanceof BiMap);
15897dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15917dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterValuesIdentifiesBiMap() {
15927dd252788645e940eada959bdde927426e2531c9Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
15930888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
15940888a09821a98ac0680fad765217302858e70fa4Paul Duffin          instanceof BiMap);
15957dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
15961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15977dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void testFilterEntriesIdentifiesBiMap() {
15987dd252788645e940eada959bdde927426e2531c9Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
15990888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
16000888a09821a98ac0680fad765217302858e70fa4Paul Duffin          instanceof BiMap);
16017dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
16021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformValues() {
16051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
16067dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
16071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
16091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformValuesSecretlySorted() {
16120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<String, Integer> map =
16130888a09821a98ac0680fad765217302858e70fa4Paul Duffin        sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
16147dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
16153c77433663281544363151bf284b0240dfd22a42Paul Duffin
16163c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
1617dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    assertTrue(transformed instanceof SortedMap);
16183c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
16193c77433663281544363151bf284b0240dfd22a42Paul Duffin
16203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
16213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testTransformValuesSecretlyNavigable() {
16223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Map<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
16233ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Map<String, Double> transformed;
16243ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
16253ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    transformed = transformValues(map, SQRT_FUNCTION);
16263ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
16273ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertTrue(transformed instanceof NavigableMap);
16283ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
16293ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    transformed =
16303ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        transformValues((SortedMap<String, Integer>) map, SQRT_FUNCTION);
16313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
16323ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertTrue(transformed instanceof NavigableMap);
16333ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
16343ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
16351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntries() {
16361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = ImmutableMap.of("a", "4", "b", "9");
16370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    EntryTransformer<String, String, String> concat =
16380888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new EntryTransformer<String, String, String>() {
16390888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override
16400888a09821a98ac0680fad765217302858e70fa4Paul Duffin          public String transformEntry(String key, String value) {
16410888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return key + value;
16420888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
16430888a09821a98ac0680fad765217302858e70fa4Paul Duffin        };
16447dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> transformed = transformEntries(map, concat);
16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
16471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesSecretlySorted() {
16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
16510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    EntryTransformer<String, String, String> concat =
16520888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new EntryTransformer<String, String, String>() {
16530888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override
16540888a09821a98ac0680fad765217302858e70fa4Paul Duffin          public String transformEntry(String key, String value) {
16550888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return key + value;
16560888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
16570888a09821a98ac0680fad765217302858e70fa4Paul Duffin        };
16587dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> transformed = transformEntries(map, concat);
16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(transformed instanceof SortedMap);
16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16643ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
16653ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testTransformEntriesSecretlyNavigable() {
16663ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
16673ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    EntryTransformer<String, String, String> concat =
16683ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        new EntryTransformer<String, String, String>() {
16693ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin          @Override
16703ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin          public String transformEntry(String key, String value) {
16713ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin            return key + value;
16723ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin          }
16733ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        };
16743ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Map<String, String> transformed;
16753ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
16763ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    transformed = transformEntries(map, concat);
16773ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
16783ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertTrue(transformed instanceof NavigableMap);
16793ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
16803ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    transformed = transformEntries((SortedMap<String, String>) map, concat);
16813ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
16823ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertTrue(transformed instanceof NavigableMap);
16833ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
16843ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
16850888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @SuppressWarnings("unused")
16861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesGenerics() {
16871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Object> map1 = ImmutableMap.<Object, Object>of(1, 2);
16881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Number> map2 = ImmutableMap.<Object, Number>of(1, 2);
16891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Integer> map3 = ImmutableMap.<Object, Integer>of(1, 2);
16901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Object> map4 = ImmutableMap.<Number, Object>of(1, 2);
16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Number> map5 = ImmutableMap.<Number, Number>of(1, 2);
16921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Integer> map6 = ImmutableMap.<Number, Integer>of(1, 2);
16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Object> map7 = ImmutableMap.<Integer, Object>of(1, 2);
16941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Number> map8 = ImmutableMap.<Integer, Number>of(1, 2);
16951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Integer> map9 = ImmutableMap.<Integer, Integer>of(1, 2);
16961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<? extends Number, ? extends Number> map0 = ImmutableMap.of(1, 2);
16971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    EntryTransformer<Number, Number, Double> transformer =
16990888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new EntryTransformer<Number, Number, Double>() {
17000888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override
17010888a09821a98ac0680fad765217302858e70fa4Paul Duffin          public Double transformEntry(Number key, Number value) {
17020888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return key.doubleValue() + value.doubleValue();
17030888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
17040888a09821a98ac0680fad765217302858e70fa4Paul Duffin        };
17051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Double> objectKeyed;
17071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Double> numberKeyed;
17081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Double> integerKeyed;
17091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    numberKeyed = transformEntries(map5, transformer);
17111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    numberKeyed = transformEntries(map6, transformer);
17121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    integerKeyed = transformEntries(map8, transformer);
17131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    integerKeyed = transformEntries(map9, transformer);
17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<? extends Number, Double> wildcarded = transformEntries(map0, transformer);
17161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't loosen the key type:
17181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map5, transformer);
17191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map6, transformer);
17201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map8, transformer);
17211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map9, transformer);
17221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // numberKeyed = transformEntries(map8, transformer);
17231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // numberKeyed = transformEntries(map9, transformer);
17241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't loosen the value type:
17261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Number, Number> looseValued1 = transformEntries(map5, transformer);
17271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Number, Number> looseValued2 = transformEntries(map6, transformer);
17281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Integer, Number> looseValued3 = transformEntries(map8, transformer);
17291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Integer, Number> looseValued4 = transformEntries(map9, transformer);
17301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't call with too loose a key:
17321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map1, transformer);
17331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map2, transformer);
17341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map3, transformer);
17351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't call with too loose a value:
17371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map1, transformer);
17381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map4, transformer);
17391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map7, transformer);
17401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesExample() {
17430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<String, Boolean> options =
17440888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableMap.of("verbose", true, "sort", false);
17450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    EntryTransformer<String, Boolean, String> flagPrefixer =
17460888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new EntryTransformer<String, Boolean, String>() {
17470888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override
17480888a09821a98ac0680fad765217302858e70fa4Paul Duffin          public String transformEntry(String key, Boolean value) {
17490888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return value ? key : "no" + key;
17500888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
17510888a09821a98ac0680fad765217302858e70fa4Paul Duffin        };
17527dd252788645e940eada959bdde927426e2531c9Paul Duffin    Map<String, String> transformed = transformEntries(options, flagPrefixer);
17531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("{verbose=verbose, sort=nosort}", transformed.toString());
17541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17567dd252788645e940eada959bdde927426e2531c9Paul Duffin  // Logically this would accept a NavigableMap, but that won't work under GWT.
17570888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static <K, V> SortedMap<K, V> sortedNotNavigable(
17580888a09821a98ac0680fad765217302858e70fa4Paul Duffin      final SortedMap<K, V> map) {
17597dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new ForwardingSortedMap<K, V>() {
17600888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override protected SortedMap<K, V> delegate() {
17617dd252788645e940eada959bdde927426e2531c9Paul Duffin        return map;
1762dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin      }
1763dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin    };
17647dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
17657dd252788645e940eada959bdde927426e2531c9Paul Duffin
17667dd252788645e940eada959bdde927426e2531c9Paul Duffin  public void testSortedMapTransformValues() {
17670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<String, Integer> map =
17680888a09821a98ac0680fad765217302858e70fa4Paul Duffin        sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
17690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<String, Double> transformed =
17700888a09821a98ac0680fad765217302858e70fa4Paul Duffin        transformValues(map, SQRT_FUNCTION);
17711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17727dd252788645e940eada959bdde927426e2531c9Paul Duffin    /*
17737dd252788645e940eada959bdde927426e2531c9Paul Duffin     * We'd like to sanity check that we didn't get a NavigableMap out, but we
17747dd252788645e940eada959bdde927426e2531c9Paul Duffin     * can't easily do so while maintaining GWT compatibility.
17757dd252788645e940eada959bdde927426e2531c9Paul Duffin     */
17761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
17771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17793ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
17803ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testNavigableMapTransformValues() {
17813ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
17823ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, Double> transformed =
17833ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        transformValues(map, SQRT_FUNCTION);
17843ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
17853ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
17863ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
17873ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
17881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapTransformEntries() {
17890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedMap<String, String> map =
17900888a09821a98ac0680fad765217302858e70fa4Paul Duffin        sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9"));
17910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    EntryTransformer<String, String, String> concat =
17920888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new EntryTransformer<String, String, String>() {
17930888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override
17940888a09821a98ac0680fad765217302858e70fa4Paul Duffin          public String transformEntry(String key, String value) {
17950888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return key + value;
17960888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
17970888a09821a98ac0680fad765217302858e70fa4Paul Duffin        };
17987dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<String, String> transformed = transformEntries(map, concat);
17993c77433663281544363151bf284b0240dfd22a42Paul Duffin
18007dd252788645e940eada959bdde927426e2531c9Paul Duffin    /*
18017dd252788645e940eada959bdde927426e2531c9Paul Duffin     * We'd like to sanity check that we didn't get a NavigableMap out, but we
18027dd252788645e940eada959bdde927426e2531c9Paul Duffin     * can't easily do so while maintaining GWT compatibility.
18037dd252788645e940eada959bdde927426e2531c9Paul Duffin     */
18043c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
18053c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
18063ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18073ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
18083ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testNavigableMapTransformEntries() {
18093ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, String> map =
18103ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        ImmutableSortedMap.of("a", "4", "b", "9");
18113ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    EntryTransformer<String, String, String> concat =
18123ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        new EntryTransformer<String, String, String>() {
18133ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin          @Override
18143ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin          public String transformEntry(String key, String value) {
18153ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin            return key + value;
18163ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin          }
18173ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        };
18183ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<String, String> transformed = transformEntries(map, concat);
18193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
18213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
18223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18233ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
18243ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  public void testUnmodifiableNavigableMap() {
18253ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    TreeMap<Integer, String> mod = Maps.newTreeMap();
18263ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    mod.put(1, "one");
18273ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    mod.put(2, "two");
18283ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    mod.put(3, "three");
18293ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18303ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    NavigableMap<Integer, String> unmod = unmodifiableNavigableMap(mod);
18313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18323ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    /* unmod is a view. */
18333ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    mod.put(4, "four");
18343ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("four", unmod.get(4));
18353ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertEquals("four", unmod.descendingMap().get(4));
18363ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18373ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    ensureNotDirectlyModifiable(unmod);
18383ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    ensureNotDirectlyModifiable(unmod.descendingMap());
18393ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    ensureNotDirectlyModifiable(unmod.headMap(2, true));
18403ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    ensureNotDirectlyModifiable(unmod.subMap(1, true, 3, true));
18413ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    ensureNotDirectlyModifiable(unmod.tailMap(2, true));
18423ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18433ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Collection<String> values = unmod.values();
18443ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18453ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      values.add("4");
18463ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18473ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18483ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18493ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18503ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      values.remove("four");
18513ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18523ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18533ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18543ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18553ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      values.removeAll(Collections.singleton("four"));
18563ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18573ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18583ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18593ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18603ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      values.retainAll(Collections.singleton("four"));
18613ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18623ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18633ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18643ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18653ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      Iterator<String> iterator = values.iterator();
18663ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      iterator.next();
18673ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      iterator.remove();
18683ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18693ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18703ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18713ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
18723ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Set<Map.Entry<Integer, String>> entries = unmod.entrySet();
18733ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18743ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
18753ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      iterator.next();
18763ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      iterator.remove();
18773ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18783ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18793ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18803ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Map.Entry<Integer, String> entry = entries.iterator().next();
18813ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18823ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry.setValue("four");
18833ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18843ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18853ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18863ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    entry = unmod.lowerEntry(1);
18873ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertNull(entry);
18883ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    entry = unmod.floorEntry(2);
18893ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18903ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry.setValue("four");
18913ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18923ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18933ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
18943ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    entry = unmod.ceilingEntry(2);
18953ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
18963ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry.setValue("four");
18973ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
18983ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
18993ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19003ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    entry = unmod.lowerEntry(2);
19013ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19023ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry.setValue("four");
19033ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19043ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19053ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19063ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    entry = unmod.higherEntry(2);
19073ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19083ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry.setValue("four");
19093ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19103ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19113ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19123ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    entry = unmod.firstEntry();
19133ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19143ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry.setValue("four");
19153ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19163ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19173ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19183ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    entry = unmod.lastEntry();
19193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry.setValue("four");
19213ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19233ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19243ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        @SuppressWarnings("unchecked")
19253ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    Map.Entry<Integer, String> entry2 =
19263ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        (Map.Entry<Integer, String>) entries.toArray()[0];
19273ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19283ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      entry2.setValue("four");
19293ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19303ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19313ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19323ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
19333ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
19343ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  @GwtIncompatible("NavigableMap")
19353ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  void ensureNotDirectlyModifiable(NavigableMap<Integer, String> unmod) {
19363ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19373ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      unmod.put(4, "four");
19383ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19393ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19403ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19413ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19423ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      unmod.putAll(Collections.singletonMap(4, "four"));
19433ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19443ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19453ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19463ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19473ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      unmod.remove("four");
19483ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19493ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19503ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19513ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19523ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      unmod.pollFirstEntry();
19533ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19543ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19553ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19563ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    try {
19573ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      unmod.pollLastEntry();
19583ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin      fail("UnsupportedOperationException expected");
19593ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    } catch (UnsupportedOperationException expected) {
19603ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    }
19613ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  }
19621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
1963