MapsTest.java revision 3c77433663281544363151bf284b0240dfd22a42
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;
203c77433663281544363151bf284b0240dfd22a42Paul Duffinimport static com.google.common.collect.Maps.transformValues;
213c77433663281544363151bf284b0240dfd22a42Paul Duffinimport static com.google.common.collect.Maps.unmodifiableNavigableMap;
223c77433663281544363151bf284b0240dfd22a42Paul Duffinimport static com.google.common.collect.testing.Helpers.mapEntry;
233c77433663281544363151bf284b0240dfd22a42Paul Duffinimport static java.util.Arrays.asList;
243c77433663281544363151bf284b0240dfd22a42Paul Duffinimport static org.truth0.Truth.ASSERT;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalence;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Functions;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicate;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Predicates;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.EntryTransformer;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps.ValueDifferenceImpl;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.SetsTest.Derived;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.EqualsTester;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester;
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase;
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException;
423c77433663281544363151bf284b0240dfd22a42Paul Duffinimport java.io.StringReader;
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.reflect.Field;
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays;
453c77433663281544363151bf284b0240dfd22a42Paul Duffinimport java.util.Collection;
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.EnumMap;
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Enumeration;
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.HashMap;
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.IdentityHashMap;
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap;
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
573c77433663281544363151bf284b0240dfd22a42Paul Duffinimport java.util.NavigableMap;
583c77433663281544363151bf284b0240dfd22a42Paul Duffinimport java.util.NavigableSet;
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Properties;
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap;
623c77433663281544363151bf284b0240dfd22a42Paul Duffinimport java.util.SortedSet;
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.TreeMap;
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ConcurrentMap;
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit test for {@code Maps}.
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class MapsTest extends TestCase {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final Comparator<Integer> SOME_COMPARATOR =
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collections.reverseOrder();
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMap() {
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<Integer, Integer> map = Maps.newHashMap();
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMapWithInitialMap() {
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new TreeMap<String, Integer>();
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<String, Integer> map = Maps.newHashMap(original);
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testHashMapGeneralizesTypes() {
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new TreeMap<String, Integer>();
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<Object, Object> map =
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.newHashMap((Map<? extends Object, ? extends Object>) original);
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCapacityForNegativeSizeFails() {
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.capacity(-1);
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Negative expected size must result in IllegalArgumentException");
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException ex) {
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Tests that nHMWES makes hash maps large enough that adding the expected
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * number of elements won't cause a rehash.
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * This test may fail miserably on non-OpenJDK environments...
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("reflection")
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testNewHashMapWithExpectedSize_wontGrow() throws Exception {
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int size = 0; size < 200; size++) {
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      HashMap<Integer, Void> map1 = Maps.newHashMapWithExpectedSize(size);
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int startSize = sizeOf(map1);
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (int i = 0; i < size; i++) {
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        map1.put(i, null);
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("table size after adding " + size + "elements",
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          startSize, sizeOf(map1));
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /*
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * Something slightly different happens when the entries are added all at
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * once; make sure that passes too.
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       */
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      HashMap<Integer, Void> map2 = Maps.newHashMapWithExpectedSize(size);
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map2.putAll(map1);
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("table size after adding " + size + "elements",
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          startSize, sizeOf(map2));
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("reflection")
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static int sizeOf(HashMap<?, ?> hashMap) throws Exception {
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Field tableField = HashMap.class.getDeclaredField("table");
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tableField.setAccessible(true);
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Object[] table = (Object[]) tableField.get(hashMap);
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return table.length;
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testCapacityForLargeSizes() {
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int[] largeExpectedSizes = new int[] {
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Integer.MAX_VALUE / 2 - 1,
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Integer.MAX_VALUE / 2,
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Integer.MAX_VALUE / 2 + 1,
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Integer.MAX_VALUE - 1,
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Integer.MAX_VALUE};
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int expectedSize : largeExpectedSizes) {
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int capacity = Maps.capacity(expectedSize);
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          "capacity (" + capacity + ") must be >= expectedSize (" + expectedSize + ")",
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          capacity >= expectedSize);
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMap() {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LinkedHashMap<Integer, Integer> map = Maps.newLinkedHashMap();
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("serial")
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMapWithInitialMap() {
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = new LinkedHashMap<String, String>() {{
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      put("Hello", "World");
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      put("first", "second");
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      put("polygene", "lubricants");
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      put("alpha", "betical");
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }};
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LinkedHashMap<String, String> copy = Maps.newLinkedHashMap(map);
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Entry<String, String>> iter = copy.entrySet().iterator();
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Entry<String, String> entry = iter.next();
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("Hello", entry.getKey());
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("World", entry.getValue());
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("first", entry.getKey());
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("second", entry.getValue());
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("polygene", entry.getKey());
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("lubricants", entry.getValue());
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(iter.hasNext());
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entry = iter.next();
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("alpha", entry.getKey());
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("betical", entry.getValue());
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(iter.hasNext());
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testLinkedHashMapGeneralizesTypes() {
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> original = new LinkedHashMap<String, Integer>();
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("a", 1);
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("b", 2);
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put("c", 3);
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<Object, Object> map
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Maps.<Object, Object>newLinkedHashMap(original);
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, map);
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testIdentityHashMap() {
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    IdentityHashMap<Integer, Integer> map = Maps.newIdentityHashMap();
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testConcurrentMap() {
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ConcurrentMap<Integer, Integer> map = Maps.newConcurrentMap();
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMap() {
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Integer, Integer> map = Maps.newTreeMap();
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapDerived() {
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Derived, Integer> map = Maps.newTreeMap();
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new Derived("foo"), 1);
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new Derived("bar"), 2);
2343c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.keySet()).has().allOf(
2353c77433663281544363151bf284b0240dfd22a42Paul Duffin        new Derived("bar"), new Derived("foo")).inOrder();
2363c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapNonGeneric() {
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<LegacyComparable, Integer> map = Maps.newTreeMap();
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new LegacyComparable("foo"), 1);
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(new LegacyComparable("bar"), 2);
2453c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.keySet()).has().allOf(
2463c77433663281544363151bf284b0240dfd22a42Paul Duffin        new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
2473c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.comparator());
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapWithComparator() {
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Integer, Integer> map = Maps.newTreeMap(SOME_COMPARATOR);
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(SOME_COMPARATOR, map.comparator());
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTreeMapWithInitialMap() {
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, Integer> map = Maps.newTreeMap();
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(5, 10);
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(3, 20);
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(1, 30);
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMap<Integer, Integer> copy = Maps.newTreeMap(map);
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(copy, map);
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(copy.comparator(), map.comparator());
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public enum SomeEnum { SOME_INSTANCE }
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMap() {
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> map = Maps.newEnumMap(SomeEnum.class);
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.emptyMap(), map);
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.put(SomeEnum.SOME_INSTANCE, 0);
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(Collections.singletonMap(SomeEnum.SOME_INSTANCE, 0), map);
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapNullClass() {
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.<SomeEnum, Long>newEnumMap((Class<MapsTest.SomeEnum>) null);
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("no exception thrown");
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEnumMap() {
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put(SomeEnum.SOME_INSTANCE, 0);
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEmptyEnumMap() {
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> original = Maps.newEnumMap(SomeEnum.class);
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNotSame(original, copy);
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialMap() {
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    HashMap<SomeEnum, Integer> original = Maps.newHashMap();
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    original.put(SomeEnum.SOME_INSTANCE, 0);
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EnumMap<SomeEnum, Integer> copy = Maps.newEnumMap(original);
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(original, copy);
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testEnumMapWithInitialEmptyMap() {
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<SomeEnum, Integer> original = Maps.newHashMap();
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.newEnumMap(original);
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("Empty map must result in an IllegalArgumentException");
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException expected) {}
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3133c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testToStringImplWithNullKeys() throws Exception {
3143c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, String> hashmap = Maps.newHashMap();
3153c77433663281544363151bf284b0240dfd22a42Paul Duffin    hashmap.put("foo", "bar");
3163c77433663281544363151bf284b0240dfd22a42Paul Duffin    hashmap.put(null, "baz");
3173c77433663281544363151bf284b0240dfd22a42Paul Duffin
3183c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
3193c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
3203c77433663281544363151bf284b0240dfd22a42Paul Duffin
3213c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testToStringImplWithNullValues() throws Exception {
3223c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, String> hashmap = Maps.newHashMap();
3233c77433663281544363151bf284b0240dfd22a42Paul Duffin    hashmap.put("foo", "bar");
3243c77433663281544363151bf284b0240dfd22a42Paul Duffin    hashmap.put("baz", null);
3253c77433663281544363151bf284b0240dfd22a42Paul Duffin
3263c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
3273c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
3283c77433663281544363151bf284b0240dfd22a42Paul Duffin
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("NullPointerTester")
3303c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testNullPointerExceptions() {
3313c77433663281544363151bf284b0240dfd22a42Paul Duffin    new NullPointerTester().testAllPublicStaticMethods(Maps.class);
3323c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final Map<Integer, Integer> EMPTY
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = Collections.emptyMap();
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final Map<Integer, Integer> SINGLETON
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = Collections.singletonMap(1, 2);
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEmptyEmpty() {
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, EMPTY);
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(diff.areEqual());
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnLeft());
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnRight());
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("equal", diff.toString());
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEmptySingleton() {
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, SINGLETON);
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnLeft());
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SINGLETON, diff.entriesOnlyOnRight());
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on right={1=2}", diff.toString());
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceSingletonEmpty() {
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> diff = Maps.difference(SINGLETON, EMPTY);
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SINGLETON, diff.entriesOnlyOnLeft());
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesOnlyOnRight());
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesInCommon());
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(EMPTY, diff.entriesDiffering());
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={1=2}", diff.toString());
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceTypical() {
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, String> left = ImmutableMap.of(
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, String> right = ImmutableMap.of(
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        1, "a", 3, "f", 5, "g", 6, "z");
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff1 = Maps.difference(left, right);
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "z"), diff1.entriesOnlyOnRight());
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(3,
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("c", "f"), 5,
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("e", "g")),
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        diff1.entriesDiffering());
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=z}: "
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(c, f), 5=(e, g)}", diff1.toString());
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff2 = Maps.difference(right, left);
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "z"), diff2.entriesOnlyOnLeft());
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff2.entriesInCommon());
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(3,
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("f", "c"), 5,
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("g", "e")),
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        diff2.entriesDiffering());
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceEquals() {
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, String> left = ImmutableMap.of(
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, String> right = ImmutableMap.of(
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        1, "a", 3, "f", 5, "g", 6, "z");
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, String> right2 = ImmutableMap.of(
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        1, "a", 3, "h", 5, "g", 6, "z");
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> original = Maps.difference(left, right);
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> same = Maps.difference(left, right);
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> reverse = Maps.difference(right, left);
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff2 = Maps.difference(left, right2);
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    new EqualsTester()
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .addEqualityGroup(original, same)
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .addEqualityGroup(reverse)
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .addEqualityGroup(diff2)
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .testEquals();
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferencePredicateTypical() {
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, String> left = ImmutableMap.of(
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, String> right = ImmutableMap.of(
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        1, "A", 3, "F", 5, "G", 6, "Z");
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // TODO(kevinb): replace with Ascii.caseInsensitiveEquivalence() when it
4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // exists
4273c77433663281544363151bf284b0240dfd22a42Paul Duffin    Equivalence<String> caseInsensitiveEquivalence = Equivalence.equals().onResultOf(
4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Function<String, String>() {
4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override public String apply(String input) {
4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return input.toLowerCase();
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        });
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff1 = Maps.difference(left, right,
4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        caseInsensitiveEquivalence);
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft());
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "Z"), diff1.entriesOnlyOnRight());
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon());
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(3,
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("c", "F"), 5,
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("e", "G")),
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        diff1.entriesDiffering());
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=Z}: "
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(c, F), 5=(e, G)}", diff1.toString());
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, String> diff2 = Maps.difference(right, left,
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        caseInsensitiveEquivalence);
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(6, "Z"), diff2.entriesOnlyOnLeft());
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight());
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(1, "A"), diff2.entriesInCommon());
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(3,
4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("F", "c"), 5,
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ValueDifferenceImpl.create("G", "e")),
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        diff2.entriesDiffering());
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=Z}: only on right={2=b, 4=d}: "
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(F, c), 5=(G, e)}", diff2.toString());
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final SortedMap<Integer, Integer> SORTED_EMPTY = Maps.newTreeMap();
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final SortedMap<Integer, Integer> SORTED_SINGLETON =
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableSortedMap.of(1, 2);
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testMapDifferenceOfSortedMapIsSorted() {
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Integer> map = SORTED_SINGLETON;
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    MapDifference<Integer, Integer> difference = Maps.difference(map, EMPTY);
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(difference instanceof SortedMapDifference);
4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEmptyEmpty() {
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, Integer> diff =
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(SORTED_EMPTY, SORTED_EMPTY);
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(diff.areEqual());
4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("equal", diff.toString());
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEmptySingleton() {
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, Integer> diff =
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(SORTED_EMPTY, SORTED_SINGLETON);
4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft());
4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnRight());
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on right={1=2}", diff.toString());
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceSingletonEmpty() {
4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, Integer> diff =
4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(SORTED_SINGLETON, SORTED_EMPTY);
4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff.areEqual());
4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnLeft());
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight());
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesInCommon());
5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(SORTED_EMPTY, diff.entriesDiffering());
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={1=2}", diff.toString());
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceTypical() {
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, String> left =
5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableSortedMap.<Integer, String>reverseOrder()
5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .put(1, "a").put(2, "b").put(3, "c").put(4, "d").put(5, "e")
5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .build();
5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, String> right =
5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, String> diff1 =
5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(left, right);
5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
5163c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().allOf(
5173c77433663281544363151bf284b0240dfd22a42Paul Duffin        Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder();
5183c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(
5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(6, "z"));
5203c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(1, "a"));
5223c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesDiffering().entrySet()).has().allOf(
5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")),
5243c77433663281544363151bf284b0240dfd22a42Paul Duffin        Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder();
5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={4=d, 2=b}: only on right={6=z}: "
5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={5=(e, g), 3=(c, f)}", diff1.toString());
5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, String> diff2 =
5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(right, left);
5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff2.areEqual());
5313c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).has().item(
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(6, "z"));
5333c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).has().allOf(
5343c77433663281544363151bf284b0240dfd22a42Paul Duffin        Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
5353c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(1, "a"));
5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of(
5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            3, ValueDifferenceImpl.create("f", "c"),
5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            5, ValueDifferenceImpl.create("g", "e")),
5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        diff2.entriesDiffering());
5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: "
5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        + "value differences={3=(f, c), 5=(g, e)}", diff2.toString());
5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceImmutable() {
5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, String> left = Maps.newTreeMap(
5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"));
5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, String> right =
5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z"));
5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, String> diff1 =
5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(left, right);
5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    left.put(6, "z");
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(diff1.areEqual());
5553c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().allOf(
5563c77433663281544363151bf284b0240dfd22a42Paul Duffin        Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
5573c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(
5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(6, "z"));
5593c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(1, "a"));
5613c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(diff1.entriesDiffering().entrySet()).has().allOf(
5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")),
5633c77433663281544363151bf284b0240dfd22a42Paul Duffin        Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder();
5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesInCommon().put(7, "x");
5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesOnlyOnLeft().put(7, "x");
5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      diff1.entriesOnlyOnRight().put(7, "x");
5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapDifferenceEquals() {
5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, String> left =
5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e");
5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, String> right =
5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z");
5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<Integer, String> right2 =
5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableSortedMap.of(1, "a", 3, "h", 5, "g", 6, "z");
5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, String> original =
5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(left, right);
5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, String> same =
5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(left, right);
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, String> reverse =
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(right, left);
5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMapDifference<Integer, String> diff2 =
5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.difference(left, right2);
5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    new EqualsTester()
5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .addEqualityGroup(original, same)
5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .addEqualityGroup(reverse)
6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .addEqualityGroup(diff2)
6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        .testEquals();
6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6043c77433663281544363151bf284b0240dfd22a42Paul Duffin  private static final Function<String, Integer> LENGTH_FUNCTION =
6053c77433663281544363151bf284b0240dfd22a42Paul Duffin      new Function<String, Integer>() {
6063c77433663281544363151bf284b0240dfd22a42Paul Duffin        @Override
6073c77433663281544363151bf284b0240dfd22a42Paul Duffin        public Integer apply(String input) {
6083c77433663281544363151bf284b0240dfd22a42Paul Duffin          return input.length();
6093c77433663281544363151bf284b0240dfd22a42Paul Duffin        }
6103c77433663281544363151bf284b0240dfd22a42Paul Duffin      };
6113c77433663281544363151bf284b0240dfd22a42Paul Duffin
6123c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMap() {
6133c77433663281544363151bf284b0240dfd22a42Paul Duffin    Set<String> strings = ImmutableSet.of("one", "two", "three");
6143c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6153c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6163c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
6173c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("five"));
6183c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
6193c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
6203c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3),
6213c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5)).inOrder();
6223c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
6233c77433663281544363151bf284b0240dfd22a42Paul Duffin
6243c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapReadsThrough() {
6253c77433663281544363151bf284b0240dfd22a42Paul Duffin    Set<String> strings = Sets.newLinkedHashSet();
6263c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6273c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6283c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6293c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("four"));
6303c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.add("four");
6313c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5, "four", 4), map);
6323c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
6333c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
6343c77433663281544363151bf284b0240dfd22a42Paul Duffin
6353c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapWritesThrough() {
6363c77433663281544363151bf284b0240dfd22a42Paul Duffin    Set<String> strings = Sets.newLinkedHashSet();
6373c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6383c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6393c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6403c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
6413c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(strings).has().allOf("one", "three").inOrder();
6423c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
6433c77433663281544363151bf284b0240dfd22a42Paul Duffin
6443c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapEmpty() {
6453c77433663281544363151bf284b0240dfd22a42Paul Duffin    Set<String> strings = ImmutableSet.of();
6463c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6473c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).isEmpty();
6483c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(map.isEmpty());
6493c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("five"));
6503c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
6513c77433663281544363151bf284b0240dfd22a42Paul Duffin
6523c77433663281544363151bf284b0240dfd22a42Paul Duffin  private static class NonNavigableSortedSet
6533c77433663281544363151bf284b0240dfd22a42Paul Duffin      extends ForwardingSortedSet<String> {
6543c77433663281544363151bf284b0240dfd22a42Paul Duffin    private final SortedSet<String> delegate = Sets.newTreeSet();
6553c77433663281544363151bf284b0240dfd22a42Paul Duffin
6563c77433663281544363151bf284b0240dfd22a42Paul Duffin    @Override
6573c77433663281544363151bf284b0240dfd22a42Paul Duffin    protected SortedSet<String> delegate() {
6583c77433663281544363151bf284b0240dfd22a42Paul Duffin      return delegate;
6593c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
6603c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
6613c77433663281544363151bf284b0240dfd22a42Paul Duffin
6623c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapReturnsSortedMapForSortedSetInput() {
6633c77433663281544363151bf284b0240dfd22a42Paul Duffin    Set<String> set = new NonNavigableSortedSet();
6643c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(Maps.asMap(set, Functions.identity()) instanceof SortedMap);
6653c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
6663c77433663281544363151bf284b0240dfd22a42Paul Duffin
6673c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapSorted() {
6683c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
6693c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6703c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6713c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
6723c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
6733c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("five"));
6743c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
6753c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
6763c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5),
6773c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3)).inOrder();
6783c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.tailMap("onea").entrySet()).has().allOf(
6793c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5),
6803c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3)).inOrder();
6813c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.subMap("one", "two").entrySet()).has().allOf(
6823c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
6833c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5)).inOrder();
6843c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
6853c77433663281544363151bf284b0240dfd22a42Paul Duffin
6863c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapSortedReadsThrough() {
6873c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
6883c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collections.addAll(strings, "one", "two", "three");
6893c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
6903c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.comparator());
6913c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
6923c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("four"));
6933c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.add("four");
6943c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(
6953c77433663281544363151bf284b0240dfd22a42Paul Duffin        ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
6963c77433663281544363151bf284b0240dfd22a42Paul Duffin        map);
6973c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
6983c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> headMap = map.headMap("two");
6993c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(
7003c77433663281544363151bf284b0240dfd22a42Paul Duffin        ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
7013c77433663281544363151bf284b0240dfd22a42Paul Duffin        headMap);
7023c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.add("five");
7033c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.remove("one");
7043c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(
7053c77433663281544363151bf284b0240dfd22a42Paul Duffin        ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
7063c77433663281544363151bf284b0240dfd22a42Paul Duffin        headMap);
7073c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
7083c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("five", 4),
7093c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("four", 4),
7103c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5),
7113c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3)).inOrder();
7123c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
7133c77433663281544363151bf284b0240dfd22a42Paul Duffin
7143c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapSortedWritesThrough() {
7153c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
7163c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collections.addAll(strings, "one", "two", "three");
7173c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
7183c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
7193c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
7203c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(strings).has().allOf("one", "three").inOrder();
7213c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
7223c77433663281544363151bf284b0240dfd22a42Paul Duffin
7233c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapSortedSubViewKeySetsDoNotSupportAdd() {
7243c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(
7253c77433663281544363151bf284b0240dfd22a42Paul Duffin        new NonNavigableSortedSet(), LENGTH_FUNCTION);
7263c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
7273c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.subMap("a", "z").keySet().add("a");
7283c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
7293c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
7303c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
7313c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
7323c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.tailMap("a").keySet().add("a");
7333c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
7343c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
7353c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
7363c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
7373c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.headMap("r").keySet().add("a");
7383c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
7393c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
7403c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
7413c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
7423c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.headMap("r").tailMap("m").keySet().add("a");
7433c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
7443c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
7453c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
7463c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
7473c77433663281544363151bf284b0240dfd22a42Paul Duffin
7483c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapSortedEmpty() {
7493c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedSet<String> strings = new NonNavigableSortedSet();
7503c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
7513c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).isEmpty();
7523c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(map.isEmpty());
7533c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("five"));
7543c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
7553c77433663281544363151bf284b0240dfd22a42Paul Duffin
7563c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
7573c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapReturnsNavigableMapForNavigableSetInput() {
7583c77433663281544363151bf284b0240dfd22a42Paul Duffin    Set<String> set = Sets.newTreeSet();
7593c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(Maps.asMap(set, Functions.identity()) instanceof NavigableMap);
7603c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
7613c77433663281544363151bf284b0240dfd22a42Paul Duffin
7623c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
7633c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapNavigable() {
7643c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableSet<String> strings =
7653c77433663281544363151bf284b0240dfd22a42Paul Duffin        Sets.newTreeSet(asList("one", "two", "three"));
7663c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
7673c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
7683c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(5), map.get("three"));
7693c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("five"));
7703c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
7713c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
7723c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5),
7733c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3)).inOrder();
7743c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.tailMap("onea").entrySet()).has().allOf(
7753c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5),
7763c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3)).inOrder();
7773c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.subMap("one", "two").entrySet()).has().allOf(
7783c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
7793c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5)).inOrder();
7803c77433663281544363151bf284b0240dfd22a42Paul Duffin
7813c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("two", 3, "three", 5),
7823c77433663281544363151bf284b0240dfd22a42Paul Duffin        map.tailMap("three", true));
7833c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "three", 5),
7843c77433663281544363151bf284b0240dfd22a42Paul Duffin        map.headMap("two", false));
7853c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("three", 5),
7863c77433663281544363151bf284b0240dfd22a42Paul Duffin        map.subMap("one", false, "tr", true));
7873c77433663281544363151bf284b0240dfd22a42Paul Duffin
7883c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("three", map.higherKey("one"));
7893c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("three", map.higherKey("r"));
7903c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("three", map.ceilingKey("r"));
7913c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("one", map.ceilingKey("one"));
7923c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(mapEntry("three", 5), map.higherEntry("one"));
7933c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(mapEntry("one", 3), map.ceilingEntry("one"));
7943c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("one", map.lowerKey("three"));
7953c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("one", map.lowerKey("r"));
7963c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("one", map.floorKey("r"));
7973c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("three", map.floorKey("three"));
7983c77433663281544363151bf284b0240dfd22a42Paul Duffin
7993c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.descendingMap().entrySet()).has().allOf(
8003c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3),
8013c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5),
8023c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3)).inOrder();
8033c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(map.headMap("three", true),
8043c77433663281544363151bf284b0240dfd22a42Paul Duffin        map.descendingMap().tailMap("three", true));
8053c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.tailMap("three", false).entrySet()).has().item(
8063c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3));
8073c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.tailMap("three", true).lowerEntry("three"));
8083c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.headMap("two", false).values()).has().allOf(3, 5).inOrder();
8093c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.headMap("two", false).descendingMap().values())
8103c77433663281544363151bf284b0240dfd22a42Paul Duffin        .has().allOf(5, 3).inOrder();
8113c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.descendingKeySet()).has().allOf(
8123c77433663281544363151bf284b0240dfd22a42Paul Duffin        "two", "three", "one").inOrder();
8133c77433663281544363151bf284b0240dfd22a42Paul Duffin
8143c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(mapEntry("one", 3), map.pollFirstEntry());
8153c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(mapEntry("two", 3), map.pollLastEntry());
8163c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(1, map.size());
8173c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
8183c77433663281544363151bf284b0240dfd22a42Paul Duffin
8193c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
8203c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapNavigableReadsThrough() {
8213c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableSet<String> strings = Sets.newTreeSet();
8223c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collections.addAll(strings, "one", "two", "three");
8233c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
8243c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.comparator());
8253c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
8263c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("four"));
8273c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.add("four");
8283c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(
8293c77433663281544363151bf284b0240dfd22a42Paul Duffin        ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
8303c77433663281544363151bf284b0240dfd22a42Paul Duffin        map);
8313c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(4), map.get("four"));
8323c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> headMap = map.headMap("two");
8333c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(
8343c77433663281544363151bf284b0240dfd22a42Paul Duffin        ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
8353c77433663281544363151bf284b0240dfd22a42Paul Duffin        headMap);
8363c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.add("five");
8373c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.remove("one");
8383c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(
8393c77433663281544363151bf284b0240dfd22a42Paul Duffin        ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
8403c77433663281544363151bf284b0240dfd22a42Paul Duffin        headMap);
8413c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
8423c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("five", 4),
8433c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("four", 4),
8443c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5),
8453c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3)).inOrder();
8463c77433663281544363151bf284b0240dfd22a42Paul Duffin
8473c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> tailMap = map.tailMap("s", true);
8483c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> subMap = map.subMap("a", true, "t", false);
8493c77433663281544363151bf284b0240dfd22a42Paul Duffin
8503c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.add("six");
8513c77433663281544363151bf284b0240dfd22a42Paul Duffin    strings.remove("two");
8523c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(tailMap.entrySet()).has().allOf(
8533c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("six", 3),
8543c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5)).inOrder();
8553c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(subMap.entrySet()).has().allOf(
8563c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("five", 4),
8573c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("four", 4),
8583c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("six", 3)).inOrder();
8593c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
8603c77433663281544363151bf284b0240dfd22a42Paul Duffin
8613c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
8623c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapNavigableWritesThrough() {
8633c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableSet<String> strings = Sets.newTreeSet();
8643c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collections.addAll(strings, "one", "two", "three");
8653c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
8663c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
8673c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(Integer.valueOf(3), map.remove("two"));
8683c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(strings).has().allOf("one", "three").inOrder();
8693c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(mapEntry("three", 5),
8703c77433663281544363151bf284b0240dfd22a42Paul Duffin        map.subMap("one", false, "zzz", true).pollLastEntry());
8713c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(strings).has().item("one");
8723c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
8733c77433663281544363151bf284b0240dfd22a42Paul Duffin
8743c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
8753c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapNavigableSubViewKeySetsDoNotSupportAdd() {
8763c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(
8773c77433663281544363151bf284b0240dfd22a42Paul Duffin        Sets.<String>newTreeSet(), LENGTH_FUNCTION);
8783c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
8793c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.descendingKeySet().add("a");
8803c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
8813c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
8823c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
8833c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
8843c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.subMap("a", true, "z", false).keySet().add("a");
8853c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
8863c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
8873c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
8883c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
8893c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.tailMap("a", true).keySet().add("a");
8903c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
8913c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
8923c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
8933c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
8943c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.headMap("r", true).keySet().add("a");
8953c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
8963c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
8973c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
8983c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
8993c77433663281544363151bf284b0240dfd22a42Paul Duffin      map.headMap("r", false).tailMap("m", true).keySet().add("a");
9003c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
9013c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
9023c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
9033c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
9043c77433663281544363151bf284b0240dfd22a42Paul Duffin
9053c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
9063c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testAsMapNavigableEmpty() {
9073c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableSet<String> strings = ImmutableSortedSet.of();
9083c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
9093c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).isEmpty();
9103c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(map.isEmpty());
9113c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(map.get("five"));
9123c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
9133c77433663281544363151bf284b0240dfd22a42Paul Duffin
9143c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testToMap() {
9153c77433663281544363151bf284b0240dfd22a42Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three");
9163c77433663281544363151bf284b0240dfd22a42Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
9173c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
9183c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
9193c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
9203c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3),
9213c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5)).inOrder();
9223c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
9233c77433663281544363151bf284b0240dfd22a42Paul Duffin
9243c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testToMapIterator() {
9253c77433663281544363151bf284b0240dfd22a42Paul Duffin    Iterator<String> strings = ImmutableList.of("one", "two", "three").iterator();
9263c77433663281544363151bf284b0240dfd22a42Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
9273c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
9283c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
9293c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
9303c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3),
9313c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5)).inOrder();
9323c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
9333c77433663281544363151bf284b0240dfd22a42Paul Duffin
9343c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testToMapWithDuplicateKeys() {
9353c77433663281544363151bf284b0240dfd22a42Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three", "two", "one");
9363c77433663281544363151bf284b0240dfd22a42Paul Duffin    ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
9373c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
9383c77433663281544363151bf284b0240dfd22a42Paul Duffin    ASSERT.that(map.entrySet()).has().allOf(
9393c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("one", 3),
9403c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("two", 3),
9413c77433663281544363151bf284b0240dfd22a42Paul Duffin        mapEntry("three", 5)).inOrder();
9423c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
9433c77433663281544363151bf284b0240dfd22a42Paul Duffin
9443c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testToMapWithNullKeys() {
9453c77433663281544363151bf284b0240dfd22a42Paul Duffin    Iterable<String> strings = Arrays.asList("one", null, "three");
9463c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
9473c77433663281544363151bf284b0240dfd22a42Paul Duffin      Maps.toMap(strings, Functions.constant("foo"));
9483c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
9493c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (NullPointerException expected) {
9503c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
9513c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
9523c77433663281544363151bf284b0240dfd22a42Paul Duffin
9533c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testToMapWithNullValues() {
9543c77433663281544363151bf284b0240dfd22a42Paul Duffin    Iterable<String> strings = ImmutableList.of("one", "two", "three");
9553c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
9563c77433663281544363151bf284b0240dfd22a42Paul Duffin      Maps.toMap(strings, Functions.constant(null));
9573c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail();
9583c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (NullPointerException expected) {
9593c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
9603c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
9613c77433663281544363151bf284b0240dfd22a42Paul Duffin
9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final BiMap<Integer, String> INT_TO_STRING_MAP =
9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      new ImmutableBiMap.Builder<Integer, String>()
9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          .put(1, "one")
9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          .put(2, "two")
9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          .put(3, "three")
9671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          .build();
9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexCollection() {
9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableMap<Integer, String> outputMap =
9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.uniqueIndex(INT_TO_STRING_MAP.values(),
9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Functions.forMap(INT_TO_STRING_MAP.inverse()));
9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(INT_TO_STRING_MAP, outputMap);
9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexIterable() {
9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableMap<Integer, String> outputMap =
9781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.uniqueIndex(new Iterable<String>() {
9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Iterator<String> iterator() {
9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return INT_TO_STRING_MAP.values().iterator();
9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        },
9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Functions.forMap(INT_TO_STRING_MAP.inverse()));
9851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(INT_TO_STRING_MAP, outputMap);
9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexIterator() {
9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableMap<Integer, String> outputMap =
9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.uniqueIndex(INT_TO_STRING_MAP.values().iterator(),
9911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Functions.forMap(INT_TO_STRING_MAP.inverse()));
9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(INT_TO_STRING_MAP, outputMap);
9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Can't create the map if more than one value maps to the same key. */
9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexDuplicates() {
9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(ImmutableSet.of("one", "uno"), Functions.constant(1));
9991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (IllegalArgumentException expected) {
10011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Null values are not allowed. */
10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexNullValue() {
10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<String> listWithNull = Lists.newArrayList((String) null);
10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(listWithNull, Functions.constant(1));
10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {
10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Null keys aren't allowed either. */
10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUniqueIndexNullKey() {
10161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<String> oneStringList = Lists.newArrayList("foo");
10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.uniqueIndex(oneStringList, Functions.constant(null));
10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {
10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("deprecation") // StringBufferInputStream
10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromProperties() throws IOException {
10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties testProp = new Properties();
10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> result = Maps.fromProperties(testProp);
10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.isEmpty());
10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp.setProperty("first", "true");
10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(1, result.size());
10361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp.setProperty("second", "null");
10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("null", result.get("second"));
10411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(2, result.size());
10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Now test values loaded from a stream.
10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String props = "test\n second = 2\n Third item :   a short  phrase   ";
10451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10463c77433663281544363151bf284b0240dfd22a42Paul Duffin    testProp.load(new StringReader(props));
10471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(4, result.size());
10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("true", result.get("first"));
10511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("", result.get("test"));
10521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("2", result.get("second"));
10531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("item :   a short  phrase   ", result.get("Third"));
10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(result.containsKey("not here"));
10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test loading system properties
10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(System.getProperties());
10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.containsKey("java.version"));
10591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test that defaults work, too.
10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    testProp = new Properties(System.getProperties());
10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String override = "test\njava.version : hidden";
10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10643c77433663281544363151bf284b0240dfd22a42Paul Duffin    testProp.load(new StringReader(override));
10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    result = Maps.fromProperties(testProp);
10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(result.size() > 2);
10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("", result.get("test"));
10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("hidden", result.get("java.version"));
10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNotSame(System.getProperty("java.version"),
10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                  result.get("java.version"));
10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("serial") // never serialized
10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromPropertiesNullKey() {
10771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties properties = new Properties() {
10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Enumeration<?> propertyNames() {
10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Iterators.asEnumeration(
10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Arrays.asList(null, "first", "second").iterator());
10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    properties.setProperty("first", "true");
10841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    properties.setProperty("second", "null");
10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.fromProperties(properties);
10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {}
10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Maps.fromProperties")
10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("serial") // never serialized
10941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testFromPropertiesNonStringKeys() {
10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Properties properties = new Properties() {
10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public Enumeration<?> propertyNames() {
10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Iterators.asEnumeration(
10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Arrays.<Object>asList(Integer.valueOf(123), "first").iterator());
10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.fromProperties(properties);
11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ClassCastException expected) {}
11061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
11091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Constructs a "nefarious" map entry with the specified key and value,
11101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * meaning an entry that is suitable for testing that map entries cannot be
11111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * modified via a nefarious implementation of equals. This is used for testing
11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * unmodifiable collections of map entries; for example, it should not be
11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * possible to access the raw (modifiable) map entry via a nefarious equals
11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * method.
11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> Map.Entry<K, V> nefariousEntry(
11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final K key, final V value) {
11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new AbstractMapEntry<K, V>() {
11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public K getKey() {
11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return key;
11211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public V getValue() {
11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return value;
11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public V setValue(V value) {
11261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          throw new UnsupportedOperationException();
11271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @SuppressWarnings("unchecked")
11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean equals(Object o) {
11303c77433663281544363151bf284b0240dfd22a42Paul Duffin          if (o instanceof Map.Entry) {
11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            Map.Entry<K, V> e = (Map.Entry<K, V>) o;
11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            e.setValue(value); // muhahaha!
11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
11341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return super.equals(o);
11351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
11381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testUnmodifiableBiMap() {
11401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<Integer, String> mod = HashBiMap.create();
11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(1, "one");
11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(2, "two");
11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(3, "three");
11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<Number, String> unmod = Maps.<Number, String>unmodifiableBiMap(mod);
11461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* No aliasing on inverse operations. */
11481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(unmod.inverse(), unmod.inverse());
11491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSame(unmod, unmod.inverse().inverse());
11501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* Unmodifiable is a view. */
11521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    mod.put(4, "four");
11531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(true, unmod.get(4).equals("four"));
11541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(true, unmod.inverse().get("four").equals(4));
11551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* UnsupportedOperationException on direct modifications. */
11571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.put(4, "four");
11591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.forcePut(4, "four");
11631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      unmod.putAll(Collections.singletonMap(4, "four"));
11671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
11701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /* UnsupportedOperationException on indirect modifications. */
11711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Number> inverse = unmod.inverse();
11721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.put("four", 4);
11741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.forcePut("four", 4);
11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      inverse.putAll(Collections.singletonMap("four", 4));
11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<String> values = unmod.values();
11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      values.remove("four");
11871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Map.Entry<Number, String>> entries = unmod.entrySet();
11901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<Number, String> entry = entries.iterator().next();
11911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entry.setValue("four");
11931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
11951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked")
11961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<Integer, String> entry2
11971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = (Map.Entry<Integer, String>) entries.toArray()[0];
11981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
11991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entry2.setValue("four");
12001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testImmutableEntry() {
12051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<String, Integer> e = Maps.immutableEntry("foo", 1);
12061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("foo", e.getKey());
12071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(1, (int) e.getValue());
12081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      e.setValue(2);
12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("foo=1", e.toString());
12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(101575, e.hashCode());
12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testImmutableEntryNull() {
12171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<String, Integer> e
12181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Maps.immutableEntry((String) null, (Integer) null);
12191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(e.getKey());
12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(e.getValue());
12211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      e.setValue(null);
12231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("UnsupportedOperationException expected");
12241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {}
12251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("null=null", e.toString());
12261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(0, e.hashCode());
12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** See {@link SynchronizedBiMapTest} for more tests. */
12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSynchronizedBiMap() {
12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Integer> bimap = HashBiMap.create();
12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    bimap.put("one", 1);
12331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BiMap<String, Integer> sync = Maps.synchronizedBiMap(bimap);
12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    bimap.put("two", 2);
12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    sync.put("three", 3);
12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSet.of(1, 2, 3), bimap.inverse().keySet());
12371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSet.of(1, 2, 3), sync.inverse().keySet());
12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final Predicate<String> NOT_LENGTH_3
12411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = new Predicate<String>() {
12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public boolean apply(String input) {
12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return input == null || input.length() != 3;
12451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
12461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final Predicate<Integer> EVEN
12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = new Predicate<Integer>() {
12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
12511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public boolean apply(Integer input) {
12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return input == null || input % 2 == 0;
12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final Predicate<Entry<String, Integer>> CORRECT_LENGTH
12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      = new Predicate<Entry<String, Integer>>() {
12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public boolean apply(Entry<String, Integer> input) {
12601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return input.getKey().length() == input.getValue();
12611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12643c77433663281544363151bf284b0240dfd22a42Paul Duffin  private static final Function<Integer, Double> SQRT_FUNCTION = new Function<Integer, Double>() {
12653c77433663281544363151bf284b0240dfd22a42Paul Duffin      @Override
12663c77433663281544363151bf284b0240dfd22a42Paul Duffin      public Double apply(Integer in) {
12673c77433663281544363151bf284b0240dfd22a42Paul Duffin        return Math.sqrt(in);
12683c77433663281544363151bf284b0240dfd22a42Paul Duffin      }
12693c77433663281544363151bf284b0240dfd22a42Paul Duffin    };
12701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12713c77433663281544363151bf284b0240dfd22a42Paul Duffin  public static class FilteredMapTest extends TestCase {
12723c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Integer> createUnfiltered() {
12733c77433663281544363151bf284b0240dfd22a42Paul Duffin      return Maps.newHashMap();
12743c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12763c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredKeysIllegalPut() {
12773c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
12783c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
12793c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("a", 1);
12803c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("b", 2);
12813c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12833c77433663281544363151bf284b0240dfd22a42Paul Duffin      try {
12843c77433663281544363151bf284b0240dfd22a42Paul Duffin        filtered.put("yyy", 3);
12853c77433663281544363151bf284b0240dfd22a42Paul Duffin        fail();
12863c77433663281544363151bf284b0240dfd22a42Paul Duffin      } catch (IllegalArgumentException expected) {}
12873c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12893c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredKeysIllegalPutAll() {
12903c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
12913c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
12923c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("a", 1);
12933c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("b", 2);
12943c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
12963c77433663281544363151bf284b0240dfd22a42Paul Duffin      try {
12973c77433663281544363151bf284b0240dfd22a42Paul Duffin        filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
12983c77433663281544363151bf284b0240dfd22a42Paul Duffin        fail();
12993c77433663281544363151bf284b0240dfd22a42Paul Duffin      } catch (IllegalArgumentException expected) {}
13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13013c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
13023c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13043c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredKeysFilteredReflectsBackingChanges() {
13053c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13063c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
13073c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("two", 2);
13083c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("three", 3);
13093c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("four", 4);
13103c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
13113c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
13123c77433663281544363151bf284b0240dfd22a42Paul Duffin
13133c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.remove("three");
13143c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
13153c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("four", 4), filtered);
13163c77433663281544363151bf284b0240dfd22a42Paul Duffin
13173c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.clear();
13183c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of(), unfiltered);
13193c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of(), filtered);
13203c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
13211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13223c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredValuesIllegalPut() {
13233c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13243c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
13253c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("a", 2);
13263c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("b", 4);
13273c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("c", 5);
13283c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
13291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13303c77433663281544363151bf284b0240dfd22a42Paul Duffin      try {
13313c77433663281544363151bf284b0240dfd22a42Paul Duffin        filtered.put("yyy", 3);
13323c77433663281544363151bf284b0240dfd22a42Paul Duffin        fail();
13333c77433663281544363151bf284b0240dfd22a42Paul Duffin      } catch (IllegalArgumentException expected) {}
13343c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
13353c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13373c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredValuesIllegalPutAll() {
13383c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13393c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
13403c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("a", 2);
13413c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("b", 4);
13423c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("c", 5);
13433c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
13441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13453c77433663281544363151bf284b0240dfd22a42Paul Duffin      try {
13463c77433663281544363151bf284b0240dfd22a42Paul Duffin        filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
13473c77433663281544363151bf284b0240dfd22a42Paul Duffin        fail();
13483c77433663281544363151bf284b0240dfd22a42Paul Duffin      } catch (IllegalArgumentException expected) {}
13493c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
13503c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13523c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredValuesIllegalSetValue() {
13533c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13543c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
13553c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("a", 2);
13563c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("b", 4);
13573c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13593c77433663281544363151bf284b0240dfd22a42Paul Duffin      Entry<String, Integer> entry = filtered.entrySet().iterator().next();
13603c77433663281544363151bf284b0240dfd22a42Paul Duffin      try {
13613c77433663281544363151bf284b0240dfd22a42Paul Duffin        entry.setValue(5);
13623c77433663281544363151bf284b0240dfd22a42Paul Duffin        fail();
13633c77433663281544363151bf284b0240dfd22a42Paul Duffin      } catch (IllegalArgumentException expected) {}
13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13653c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
13663c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
13683c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredValuesClear() {
13693c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13703c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("one", 1);
13713c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("two", 2);
13723c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("three", 3);
13733c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("four", 4);
13743c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
13753c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
13763c77433663281544363151bf284b0240dfd22a42Paul Duffin          unfiltered);
13773c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
13783c77433663281544363151bf284b0240dfd22a42Paul Duffin
13793c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.clear();
13803c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
13813c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(filtered.isEmpty());
13823c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
13833c77433663281544363151bf284b0240dfd22a42Paul Duffin
13843c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredEntriesIllegalPut() {
13853c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
13863c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("cat", 3);
13873c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("dog", 2);
13883c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("horse", 5);
13893c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered
13903c77433663281544363151bf284b0240dfd22a42Paul Duffin          = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
13913c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
13923c77433663281544363151bf284b0240dfd22a42Paul Duffin
13933c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("chicken", 7);
13943c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
13953c77433663281544363151bf284b0240dfd22a42Paul Duffin
13963c77433663281544363151bf284b0240dfd22a42Paul Duffin      try {
13973c77433663281544363151bf284b0240dfd22a42Paul Duffin        filtered.put("cow", 7);
13983c77433663281544363151bf284b0240dfd22a42Paul Duffin        fail();
13993c77433663281544363151bf284b0240dfd22a42Paul Duffin      } catch (IllegalArgumentException expected) {}
14003c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
14013c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14023c77433663281544363151bf284b0240dfd22a42Paul Duffin
14033c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredEntriesIllegalPutAll() {
14043c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14053c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("cat", 3);
14063c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("dog", 2);
14073c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("horse", 5);
14083c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered
14093c77433663281544363151bf284b0240dfd22a42Paul Duffin          = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
14103c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
14113c77433663281544363151bf284b0240dfd22a42Paul Duffin
14123c77433663281544363151bf284b0240dfd22a42Paul Duffin      filtered.put("chicken", 7);
14133c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
14143c77433663281544363151bf284b0240dfd22a42Paul Duffin
14153c77433663281544363151bf284b0240dfd22a42Paul Duffin      try {
14163c77433663281544363151bf284b0240dfd22a42Paul Duffin        filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
14173c77433663281544363151bf284b0240dfd22a42Paul Duffin        fail();
14183c77433663281544363151bf284b0240dfd22a42Paul Duffin      } catch (IllegalArgumentException expected) {}
14193c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
14203c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14223c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredEntriesObjectPredicate() {
14233c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14243c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("cat", 3);
14253c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("dog", 2);
14263c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("horse", 5);
14273c77433663281544363151bf284b0240dfd22a42Paul Duffin      Predicate<Object> predicate = Predicates.alwaysFalse();
14283c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered
14293c77433663281544363151bf284b0240dfd22a42Paul Duffin          = Maps.filterEntries(unfiltered, predicate);
14303c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(filtered.isEmpty());
14313c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14323c77433663281544363151bf284b0240dfd22a42Paul Duffin
14333c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilteredEntriesWildCardEntryPredicate() {
14343c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> unfiltered = createUnfiltered();
14353c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("cat", 3);
14363c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("dog", 2);
14373c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("horse", 5);
14383c77433663281544363151bf284b0240dfd22a42Paul Duffin      Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
14393c77433663281544363151bf284b0240dfd22a42Paul Duffin        @Override
14403c77433663281544363151bf284b0240dfd22a42Paul Duffin        public boolean apply(Entry<?, ?> input) {
14413c77433663281544363151bf284b0240dfd22a42Paul Duffin          return "cat".equals(input.getKey())
14423c77433663281544363151bf284b0240dfd22a42Paul Duffin              || Integer.valueOf(2) == input.getValue();
14433c77433663281544363151bf284b0240dfd22a42Paul Duffin        }
14443c77433663281544363151bf284b0240dfd22a42Paul Duffin      };
14453c77433663281544363151bf284b0240dfd22a42Paul Duffin      Map<String, Integer> filtered
14463c77433663281544363151bf284b0240dfd22a42Paul Duffin          = Maps.filterEntries(unfiltered, predicate);
14473c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
14483c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
14501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14513c77433663281544363151bf284b0240dfd22a42Paul Duffin  public static class FilteredSortedMapTest extends FilteredMapTest {
14523c77433663281544363151bf284b0240dfd22a42Paul Duffin    @Override
14533c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> createUnfiltered() {
14543c77433663281544363151bf284b0240dfd22a42Paul Duffin      return Maps.newTreeMap();
14553c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
14573c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilterKeysIdentifiesSortedMap() {
14583c77433663281544363151bf284b0240dfd22a42Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
14593c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
14603c77433663281544363151bf284b0240dfd22a42Paul Duffin          instanceof SortedMap);
14613c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14623c77433663281544363151bf284b0240dfd22a42Paul Duffin
14633c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilterValuesIdentifiesSortedMap() {
14643c77433663281544363151bf284b0240dfd22a42Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
14653c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
14663c77433663281544363151bf284b0240dfd22a42Paul Duffin          instanceof SortedMap);
14673c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14683c77433663281544363151bf284b0240dfd22a42Paul Duffin
14693c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilterEntriesIdentifiesSortedMap() {
14703c77433663281544363151bf284b0240dfd22a42Paul Duffin      SortedMap<String, Integer> map = createUnfiltered();
14713c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
14723c77433663281544363151bf284b0240dfd22a42Paul Duffin          instanceof SortedMap);
14733c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14743c77433663281544363151bf284b0240dfd22a42Paul Duffin
14753c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFirstAndLastKeyFilteredMap() {
14763c77433663281544363151bf284b0240dfd22a42Paul Duffin      SortedMap<String, Integer> unfiltered = createUnfiltered();
14773c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("apple", 2);
14783c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("banana", 6);
14793c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("cat", 3);
14803c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("dog", 5);
14813c77433663281544363151bf284b0240dfd22a42Paul Duffin
14823c77433663281544363151bf284b0240dfd22a42Paul Duffin      SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
14833c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals("banana", filtered.firstKey());
14843c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals("cat", filtered.lastKey());
14853c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
14863c77433663281544363151bf284b0240dfd22a42Paul Duffin
14873c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testHeadSubTailMap_FilteredMap() {
14883c77433663281544363151bf284b0240dfd22a42Paul Duffin      SortedMap<String, Integer> unfiltered = createUnfiltered();
14893c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("apple", 2);
14903c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("banana", 6);
14913c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("cat", 4);
14923c77433663281544363151bf284b0240dfd22a42Paul Duffin      unfiltered.put("dog", 3);
14933c77433663281544363151bf284b0240dfd22a42Paul Duffin      SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
14943c77433663281544363151bf284b0240dfd22a42Paul Duffin
14953c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("banana", 6), filtered.headMap("dog"));
14963c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of(), filtered.headMap("banana"));
14973c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.headMap("emu"));
14983c77433663281544363151bf284b0240dfd22a42Paul Duffin
14993c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("banana", 6), filtered.subMap("banana", "dog"));
15003c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("dog", 3), filtered.subMap("cat", "emu"));
15013c77433663281544363151bf284b0240dfd22a42Paul Duffin
15023c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("dog", 3), filtered.tailMap("cat"));
15033c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.tailMap("banana"));
15043c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
15051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15073c77433663281544363151bf284b0240dfd22a42Paul Duffin  public static class FilteredBiMapTest extends FilteredMapTest {
15083c77433663281544363151bf284b0240dfd22a42Paul Duffin    @Override
15093c77433663281544363151bf284b0240dfd22a42Paul Duffin    BiMap<String, Integer> createUnfiltered() {
15103c77433663281544363151bf284b0240dfd22a42Paul Duffin      return HashBiMap.create();
15113c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
15121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15133c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilterKeysIdentifiesBiMap() {
15143c77433663281544363151bf284b0240dfd22a42Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
15153c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
15163c77433663281544363151bf284b0240dfd22a42Paul Duffin          instanceof BiMap);
15173c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
15181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15193c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilterValuesIdentifiesBiMap() {
15203c77433663281544363151bf284b0240dfd22a42Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
15213c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
15223c77433663281544363151bf284b0240dfd22a42Paul Duffin          instanceof BiMap);
15233c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
15241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15253c77433663281544363151bf284b0240dfd22a42Paul Duffin    public void testFilterEntriesIdentifiesBiMap() {
15263c77433663281544363151bf284b0240dfd22a42Paul Duffin      BiMap<String, Integer> map = createUnfiltered();
15273c77433663281544363151bf284b0240dfd22a42Paul Duffin      assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
15283c77433663281544363151bf284b0240dfd22a42Paul Duffin          instanceof BiMap);
15293c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
15301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformValues() {
15331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
15343c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
15351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
15371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformValuesSecretlySorted() {
15403c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Integer> map =
15413c77433663281544363151bf284b0240dfd22a42Paul Duffin        sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
15423c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
15431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
15451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(transformed instanceof SortedMap);
15461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15483c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
15493c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testTransformValuesSecretlyNavigable() {
15503c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
15513c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, Double> transformed;
15523c77433663281544363151bf284b0240dfd22a42Paul Duffin
15533c77433663281544363151bf284b0240dfd22a42Paul Duffin    transformed = transformValues(map, SQRT_FUNCTION);
15543c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
15553c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(transformed instanceof NavigableMap);
15563c77433663281544363151bf284b0240dfd22a42Paul Duffin
15573c77433663281544363151bf284b0240dfd22a42Paul Duffin    transformed =
15583c77433663281544363151bf284b0240dfd22a42Paul Duffin        transformValues((SortedMap<String, Integer>) map, SQRT_FUNCTION);
15593c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
15603c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(transformed instanceof NavigableMap);
15613c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
15623c77433663281544363151bf284b0240dfd22a42Paul Duffin
15631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntries() {
15641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = ImmutableMap.of("a", "4", "b", "9");
15651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EntryTransformer<String, String, String> concat =
15661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new EntryTransformer<String, String, String>() {
15671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
15681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public String transformEntry(String key, String value) {
15691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return key + value;
15701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
15711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
15723c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, String> transformed = transformEntries(map, concat);
15731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
15751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesSecretlySorted() {
15781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
15791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EntryTransformer<String, String, String> concat =
15801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new EntryTransformer<String, String, String>() {
15811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
15821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public String transformEntry(String key, String value) {
15831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return key + value;
15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
15851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
15863c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, String> transformed = transformEntries(map, concat);
15871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
15891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(transformed instanceof SortedMap);
15901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
15911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
15923c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
15933c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testTransformEntriesSecretlyNavigable() {
15943c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
15953c77433663281544363151bf284b0240dfd22a42Paul Duffin    EntryTransformer<String, String, String> concat =
15963c77433663281544363151bf284b0240dfd22a42Paul Duffin        new EntryTransformer<String, String, String>() {
15973c77433663281544363151bf284b0240dfd22a42Paul Duffin          @Override
15983c77433663281544363151bf284b0240dfd22a42Paul Duffin          public String transformEntry(String key, String value) {
15993c77433663281544363151bf284b0240dfd22a42Paul Duffin            return key + value;
16003c77433663281544363151bf284b0240dfd22a42Paul Duffin          }
16013c77433663281544363151bf284b0240dfd22a42Paul Duffin        };
16023c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, String> transformed;
16033c77433663281544363151bf284b0240dfd22a42Paul Duffin
16043c77433663281544363151bf284b0240dfd22a42Paul Duffin    transformed = transformEntries(map, concat);
16053c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
16063c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(transformed instanceof NavigableMap);
16073c77433663281544363151bf284b0240dfd22a42Paul Duffin
16083c77433663281544363151bf284b0240dfd22a42Paul Duffin    transformed = transformEntries((SortedMap<String, String>) map, concat);
16093c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
16103c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertTrue(transformed instanceof NavigableMap);
16113c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
16123c77433663281544363151bf284b0240dfd22a42Paul Duffin
16131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesGenerics() {
16141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Object> map1 = ImmutableMap.<Object, Object>of(1, 2);
16151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Number> map2 = ImmutableMap.<Object, Number>of(1, 2);
16161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Integer> map3 = ImmutableMap.<Object, Integer>of(1, 2);
16171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Object> map4 = ImmutableMap.<Number, Object>of(1, 2);
16181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Number> map5 = ImmutableMap.<Number, Number>of(1, 2);
16191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Integer> map6 = ImmutableMap.<Number, Integer>of(1, 2);
16201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Object> map7 = ImmutableMap.<Integer, Object>of(1, 2);
16211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Number> map8 = ImmutableMap.<Integer, Number>of(1, 2);
16221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Integer> map9 = ImmutableMap.<Integer, Integer>of(1, 2);
16231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<? extends Number, ? extends Number> map0 = ImmutableMap.of(1, 2);
16241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EntryTransformer<Number, Number, Double> transformer =
16261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new EntryTransformer<Number, Number, Double>() {
16271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
16281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Double transformEntry(Number key, Number value) {
16291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return key.doubleValue() + value.doubleValue();
16301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
16311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
16321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Object, Double> objectKeyed;
16341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Number, Double> numberKeyed;
16351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<Integer, Double> integerKeyed;
16361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    numberKeyed = transformEntries(map5, transformer);
16381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    numberKeyed = transformEntries(map6, transformer);
16391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    integerKeyed = transformEntries(map8, transformer);
16401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    integerKeyed = transformEntries(map9, transformer);
16411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<? extends Number, Double> wildcarded = transformEntries(map0, transformer);
16431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't loosen the key type:
16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map5, transformer);
16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map6, transformer);
16471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map8, transformer);
16481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // objectKeyed = transformEntries(map9, transformer);
16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // numberKeyed = transformEntries(map8, transformer);
16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // numberKeyed = transformEntries(map9, transformer);
16511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't loosen the value type:
16531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Number, Number> looseValued1 = transformEntries(map5, transformer);
16541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Number, Number> looseValued2 = transformEntries(map6, transformer);
16551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Integer, Number> looseValued3 = transformEntries(map8, transformer);
16561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Map<Integer, Number> looseValued4 = transformEntries(map9, transformer);
16571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't call with too loose a key:
16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map1, transformer);
16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map2, transformer);
16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map3, transformer);
16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Can't call with too loose a value:
16641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map1, transformer);
16651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map4, transformer);
16661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // transformEntries(map7, transformer);
16671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntriesExample() {
16701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Boolean> options =
16711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableMap.of("verbose", true, "sort", false);
16721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EntryTransformer<String, Boolean, String> flagPrefixer =
16731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new EntryTransformer<String, Boolean, String>() {
16741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
16751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public String transformEntry(String key, Boolean value) {
16761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return value ? key : "no" + key;
16771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
16781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
16793c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map<String, String> transformed = transformEntries(options, flagPrefixer);
16801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("{verbose=verbose, sort=nosort}", transformed.toString());
16811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16833c77433663281544363151bf284b0240dfd22a42Paul Duffin  // Logically this would accept a NavigableMap, but that won't work under GWT.
16843c77433663281544363151bf284b0240dfd22a42Paul Duffin  private static <K, V> SortedMap<K, V> sortedNotNavigable(
16853c77433663281544363151bf284b0240dfd22a42Paul Duffin      final SortedMap<K, V> map) {
16863c77433663281544363151bf284b0240dfd22a42Paul Duffin    return new ForwardingSortedMap<K, V>() {
16873c77433663281544363151bf284b0240dfd22a42Paul Duffin      @Override protected SortedMap<K, V> delegate() {
16883c77433663281544363151bf284b0240dfd22a42Paul Duffin        return map;
16893c77433663281544363151bf284b0240dfd22a42Paul Duffin      }
16903c77433663281544363151bf284b0240dfd22a42Paul Duffin    };
16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
16921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapTransformValues() {
16943c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, Integer> map =
16953c77433663281544363151bf284b0240dfd22a42Paul Duffin        sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
16961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedMap<String, Double> transformed =
16973c77433663281544363151bf284b0240dfd22a42Paul Duffin        transformValues(map, SQRT_FUNCTION);
16983c77433663281544363151bf284b0240dfd22a42Paul Duffin
16993c77433663281544363151bf284b0240dfd22a42Paul Duffin    /*
17003c77433663281544363151bf284b0240dfd22a42Paul Duffin     * We'd like to sanity check that we didn't get a NavigableMap out, but we
17013c77433663281544363151bf284b0240dfd22a42Paul Duffin     * can't easily do so while maintaining GWT compatibility.
17023c77433663281544363151bf284b0240dfd22a42Paul Duffin     */
17033c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
17043c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
17053c77433663281544363151bf284b0240dfd22a42Paul Duffin
17063c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
17073c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testNavigableMapTransformValues() {
17083c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
17093c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, Double> transformed =
17103c77433663281544363151bf284b0240dfd22a42Paul Duffin        transformValues(map, SQRT_FUNCTION);
17111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
17131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSortedMapTransformEntries() {
17163c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, String> map =
17173c77433663281544363151bf284b0240dfd22a42Paul Duffin        sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9"));
17181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    EntryTransformer<String, String, String> concat =
17191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new EntryTransformer<String, String, String>() {
17201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
17211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public String transformEntry(String key, String value) {
17221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return key + value;
17231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
17241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
17253c77433663281544363151bf284b0240dfd22a42Paul Duffin    SortedMap<String, String> transformed = transformEntries(map, concat);
17261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17273c77433663281544363151bf284b0240dfd22a42Paul Duffin    /*
17283c77433663281544363151bf284b0240dfd22a42Paul Duffin     * We'd like to sanity check that we didn't get a NavigableMap out, but we
17293c77433663281544363151bf284b0240dfd22a42Paul Duffin     * can't easily do so while maintaining GWT compatibility.
17303c77433663281544363151bf284b0240dfd22a42Paul Duffin     */
17311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
17321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
17331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17343c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
17353c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testNavigableMapTransformEntries() {
17363c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, String> map =
17373c77433663281544363151bf284b0240dfd22a42Paul Duffin        ImmutableSortedMap.of("a", "4", "b", "9");
17383c77433663281544363151bf284b0240dfd22a42Paul Duffin    EntryTransformer<String, String, String> concat =
17393c77433663281544363151bf284b0240dfd22a42Paul Duffin        new EntryTransformer<String, String, String>() {
17403c77433663281544363151bf284b0240dfd22a42Paul Duffin          @Override
17413c77433663281544363151bf284b0240dfd22a42Paul Duffin          public String transformEntry(String key, String value) {
17423c77433663281544363151bf284b0240dfd22a42Paul Duffin            return key + value;
17433c77433663281544363151bf284b0240dfd22a42Paul Duffin          }
17443c77433663281544363151bf284b0240dfd22a42Paul Duffin        };
17453c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<String, String> transformed = transformEntries(map, concat);
17463c77433663281544363151bf284b0240dfd22a42Paul Duffin
17473c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
17483c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
17493c77433663281544363151bf284b0240dfd22a42Paul Duffin
17503c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
17513c77433663281544363151bf284b0240dfd22a42Paul Duffin  public void testUnmodifiableNavigableMap() {
17523c77433663281544363151bf284b0240dfd22a42Paul Duffin    TreeMap<Integer, String> mod = Maps.newTreeMap();
17533c77433663281544363151bf284b0240dfd22a42Paul Duffin    mod.put(1, "one");
17543c77433663281544363151bf284b0240dfd22a42Paul Duffin    mod.put(2, "two");
17553c77433663281544363151bf284b0240dfd22a42Paul Duffin    mod.put(3, "three");
17563c77433663281544363151bf284b0240dfd22a42Paul Duffin
17573c77433663281544363151bf284b0240dfd22a42Paul Duffin    NavigableMap<Integer, String> unmod = unmodifiableNavigableMap(mod);
17583c77433663281544363151bf284b0240dfd22a42Paul Duffin
17593c77433663281544363151bf284b0240dfd22a42Paul Duffin    /* unmod is a view. */
17603c77433663281544363151bf284b0240dfd22a42Paul Duffin    mod.put(4, "four");
17613c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("four", unmod.get(4));
17623c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertEquals("four", unmod.descendingMap().get(4));
17633c77433663281544363151bf284b0240dfd22a42Paul Duffin
17643c77433663281544363151bf284b0240dfd22a42Paul Duffin    ensureNotDirectlyModifiable(unmod);
17653c77433663281544363151bf284b0240dfd22a42Paul Duffin    ensureNotDirectlyModifiable(unmod.descendingMap());
17663c77433663281544363151bf284b0240dfd22a42Paul Duffin    ensureNotDirectlyModifiable(unmod.headMap(2, true));
17673c77433663281544363151bf284b0240dfd22a42Paul Duffin    ensureNotDirectlyModifiable(unmod.subMap(1, true, 3, true));
17683c77433663281544363151bf284b0240dfd22a42Paul Duffin    ensureNotDirectlyModifiable(unmod.tailMap(2, true));
17693c77433663281544363151bf284b0240dfd22a42Paul Duffin
17703c77433663281544363151bf284b0240dfd22a42Paul Duffin    Collection<String> values = unmod.values();
17713c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
17723c77433663281544363151bf284b0240dfd22a42Paul Duffin      values.add("4");
17733c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
17743c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
17751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17763c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
17773c77433663281544363151bf284b0240dfd22a42Paul Duffin      values.remove("four");
17783c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
17793c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
17801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17813c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
17823c77433663281544363151bf284b0240dfd22a42Paul Duffin      values.removeAll(Collections.singleton("four"));
17833c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
17843c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
17851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17863c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
17873c77433663281544363151bf284b0240dfd22a42Paul Duffin      values.retainAll(Collections.singleton("four"));
17883c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
17893c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
17901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17913c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
17923c77433663281544363151bf284b0240dfd22a42Paul Duffin      Iterator<String> iterator = values.iterator();
17933c77433663281544363151bf284b0240dfd22a42Paul Duffin      iterator.next();
17943c77433663281544363151bf284b0240dfd22a42Paul Duffin      iterator.remove();
17953c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
17963c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
17971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
17981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
17993c77433663281544363151bf284b0240dfd22a42Paul Duffin    Set<Map.Entry<Integer, String>> entries = unmod.entrySet();
18003c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18013c77433663281544363151bf284b0240dfd22a42Paul Duffin      Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
18023c77433663281544363151bf284b0240dfd22a42Paul Duffin      iterator.next();
18033c77433663281544363151bf284b0240dfd22a42Paul Duffin      iterator.remove();
18043c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18053c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
18073c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map.Entry<Integer, String> entry = entries.iterator().next();
18083c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18093c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry.setValue("four");
18103c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18113c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18123c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18133c77433663281544363151bf284b0240dfd22a42Paul Duffin    entry = unmod.lowerEntry(1);
18143c77433663281544363151bf284b0240dfd22a42Paul Duffin    assertNull(entry);
18153c77433663281544363151bf284b0240dfd22a42Paul Duffin    entry = unmod.floorEntry(2);
18163c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18173c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry.setValue("four");
18183c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18193c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18203c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18213c77433663281544363151bf284b0240dfd22a42Paul Duffin    entry = unmod.ceilingEntry(2);
18223c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18233c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry.setValue("four");
18243c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18253c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18263c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18273c77433663281544363151bf284b0240dfd22a42Paul Duffin    entry = unmod.lowerEntry(2);
18283c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18293c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry.setValue("four");
18303c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18313c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18323c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18333c77433663281544363151bf284b0240dfd22a42Paul Duffin    entry = unmod.higherEntry(2);
18343c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18353c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry.setValue("four");
18363c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18373c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18383c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18393c77433663281544363151bf284b0240dfd22a42Paul Duffin    entry = unmod.firstEntry();
18403c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18413c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry.setValue("four");
18423c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18433c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18443c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18453c77433663281544363151bf284b0240dfd22a42Paul Duffin    entry = unmod.lastEntry();
18463c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18473c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry.setValue("four");
18483c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18493c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18503c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18513c77433663281544363151bf284b0240dfd22a42Paul Duffin        @SuppressWarnings("unchecked")
18523c77433663281544363151bf284b0240dfd22a42Paul Duffin    Map.Entry<Integer, String> entry2 =
18533c77433663281544363151bf284b0240dfd22a42Paul Duffin        (Map.Entry<Integer, String>) entries.toArray()[0];
18543c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18553c77433663281544363151bf284b0240dfd22a42Paul Duffin      entry2.setValue("four");
18563c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18573c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18583c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18593c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
18601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
18613c77433663281544363151bf284b0240dfd22a42Paul Duffin  @GwtIncompatible("NavigableMap")
18623c77433663281544363151bf284b0240dfd22a42Paul Duffin  void ensureNotDirectlyModifiable(NavigableMap<Integer, String> unmod) {
18633c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18643c77433663281544363151bf284b0240dfd22a42Paul Duffin      unmod.put(4, "four");
18653c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18663c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18673c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18683c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18693c77433663281544363151bf284b0240dfd22a42Paul Duffin      unmod.putAll(Collections.singletonMap(4, "four"));
18703c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18713c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18723c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18733c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18743c77433663281544363151bf284b0240dfd22a42Paul Duffin      unmod.remove("four");
18753c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18763c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18773c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18783c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18793c77433663281544363151bf284b0240dfd22a42Paul Duffin      unmod.pollFirstEntry();
18803c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18813c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18823c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
18833c77433663281544363151bf284b0240dfd22a42Paul Duffin    try {
18843c77433663281544363151bf284b0240dfd22a42Paul Duffin      unmod.pollLastEntry();
18853c77433663281544363151bf284b0240dfd22a42Paul Duffin      fail("UnsupportedOperationException expected");
18863c77433663281544363151bf284b0240dfd22a42Paul Duffin    } catch (UnsupportedOperationException expected) {
18871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
18881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
18891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
1890