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.testing.google;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static junit.framework.TestCase.assertEquals;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static junit.framework.TestCase.assertTrue;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static junit.framework.TestCase.fail;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.ArrayListMultimap;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.LinkedHashMultiset;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Lists;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Multimap;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Multiset;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ArrayList;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A series of tests that support asserting that collections cannot be
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modified, either through direct or indirect means.
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Robert Konigsberg
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class UnmodifiableCollectionTests {
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static void assertMapEntryIsUnmodifiable(Entry<?, ?> entry) {
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      entry.setValue(null);
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("setValue on unmodifiable Map.Entry succeeded");
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Verifies that an Iterator is unmodifiable.
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>This test only works with iterators that iterate over a finite set.
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static void assertIteratorIsUnmodifiable(Iterator<?> iterator) {
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    while (iterator.hasNext()) {
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      iterator.next();
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        iterator.remove();
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Remove on unmodifiable iterator succeeded");
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (UnsupportedOperationException expected) {
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Asserts that two iterators contain elements in tandem.
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>This test only works with iterators that iterate over a finite set.
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static void assertIteratorsInOrder(
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Iterator<?> expectedIterator, Iterator<?> actualIterator) {
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int i = 0;
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    while (expectedIterator.hasNext()) {
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Object expected = expectedIterator.next();
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          "index " + i + " expected <" + expected + "., actual is exhausted",
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        actualIterator.hasNext());
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Object actual = actualIterator.next();
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertEquals("index " + i, expected, actual);
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      i++;
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (actualIterator.hasNext()) {
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("index " + i
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          + ", expected is exhausted, actual <" + actualIterator.next() + ">");
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Verifies that a collection is immutable.
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>A collection is considered immutable if:
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <ol>
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All its mutation methods result in UnsupportedOperationException, and
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * do not change the underlying contents.
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All methods that return objects that can indirectly mutate the
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * collection throw UnsupportedOperationException when those mutators
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * are called.
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * </ol>
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param collection the presumed-immutable collection
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param sampleElement an element of the same type as that contained by
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code collection}. {@code collection} may or may not have {@code
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * sampleElement} as a member.
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> void assertCollectionIsUnmodifiable(
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<E> collection, E sampleElement) {
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<E> siblingCollection = new ArrayList<E>();
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    siblingCollection.add(sampleElement);
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<E> copy = new ArrayList<E>();
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    copy.addAll(collection);
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      collection.add(sampleElement);
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("add succeeded on unmodifiable collection");
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(copy, collection);
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      collection.addAll(siblingCollection);
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("addAll succeeded on unmodifiable collection");
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(copy, collection);
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      collection.clear();
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("clear succeeded on unmodifiable collection");
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(copy, collection);
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertIteratorIsUnmodifiable(collection.iterator());
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(copy, collection);
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      collection.remove(sampleElement);
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("remove succeeded on unmodifiable collection");
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(copy, collection);
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      collection.removeAll(siblingCollection);
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("removeAll succeeded on unmodifiable collection");
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(copy, collection);
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      collection.retainAll(siblingCollection);
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("retainAll succeeded on unmodifiable collection");
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(copy, collection);
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Verifies that a set is immutable.
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>A set is considered immutable if:
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <ol>
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All its mutation methods result in UnsupportedOperationException, and
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * do not change the underlying contents.
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All methods that return objects that can indirectly mutate the
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * set throw UnsupportedOperationException when those mutators
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * are called.
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * </ol>
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param set the presumed-immutable set
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param sampleElement an element of the same type as that contained by
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code set}. {@code set} may or may not have {@code sampleElement} as a
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * member.
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> void assertSetIsUnmodifiable(
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<E> set, E sampleElement) {
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionIsUnmodifiable(set, sampleElement);
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Verifies that a multiset is immutable.
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>A multiset is considered immutable if:
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <ol>
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All its mutation methods result in UnsupportedOperationException, and
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * do not change the underlying contents.
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All methods that return objects that can indirectly mutate the
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multiset throw UnsupportedOperationException when those mutators
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * are called.
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * </ol>
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param multiset the presumed-immutable multiset
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param sampleElement an element of the same type as that contained by
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code multiset}. {@code multiset} may or may not have {@code
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * sampleElement} as a member.
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> void assertMultisetIsUnmodifiable(Multiset<E> multiset,
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      final E sampleElement) {
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Multiset<E> copy = LinkedHashMultiset.create(multiset);
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(multiset, copy);
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Multiset is a collection, so we can use all those tests.
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionIsUnmodifiable(multiset, sampleElement);
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(multiset, copy);
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multiset.add(sampleElement, 2);
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("add(Object, int) succeeded on unmodifiable collection");
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(multiset, copy);
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multiset.remove(sampleElement, 2);
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("remove(Object, int) succeeded on unmodifiable collection");
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(multiset, copy);
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(multiset, copy);
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSetIsUnmodifiable(multiset.elementSet(), sampleElement);
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(multiset, copy);
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSetIsUnmodifiable(
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multiset.entrySet(), new Multiset.Entry<E>() {
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public int getCount() {
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return 1;
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public E getElement() {
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return sampleElement;
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      });
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionsAreEquivalent(multiset, copy);
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Verifies that a multimap is immutable.
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>A multimap is considered immutable if:
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <ol>
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All its mutation methods result in UnsupportedOperationException, and
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * do not change the underlying contents.
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <li>All methods that return objects that can indirectly mutate the
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multimap throw UnsupportedOperationException when those mutators
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * </ol>
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param multimap the presumed-immutable multimap
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param sampleKey a key of the same type as that contained by
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code multimap}. {@code multimap} may or may not have {@code sampleKey} as
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * a key.
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param sampleValue a key of the same type as that contained by
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code multimap}. {@code multimap} may or may not have {@code sampleValue}
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * as a key.
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <K, V> void assertMultimapIsUnmodifiable(
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<K, V> multimap, final K sampleKey, final V sampleValue) {
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<Entry<K, V>> originalEntries =
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collections.unmodifiableList(Lists.newArrayList(multimap.entries()));
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<V> sampleValueAsCollection = Collections.singleton(sampleValue);
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #clear()
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.clear();
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("clear succeeded on unmodifiable multimap");
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test asMap().entrySet()
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSetIsUnmodifiable(
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.asMap().entrySet(),
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.immutableEntry(sampleKey, sampleValueAsCollection));
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #values()
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!multimap.isEmpty()) {
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<V> values =
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          multimap.asMap().entrySet().iterator().next().getValue();
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertCollectionIsUnmodifiable(values, sampleValue);
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #entries()
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionIsUnmodifiable(
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.entries(),
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Maps.immutableEntry(sampleKey, sampleValue));
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Iterate over every element in the entry set
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Entry<K, V> entry : multimap.entries()) {
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertMapEntryIsUnmodifiable(entry);
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #keys()
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultisetIsUnmodifiable(multimap.keys(), sampleKey);
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #keySet()
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertSetIsUnmodifiable(multimap.keySet(), sampleKey);
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #get()
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!multimap.isEmpty()) {
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      K key = multimap.keySet().iterator().next();
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertCollectionIsUnmodifiable(multimap.get(key), sampleValue);
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertMultimapRemainsUnmodified(multimap, originalEntries);
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #put()
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.put(sampleKey, sampleValue);
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("put succeeded on unmodifiable multimap");
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #putAll(K, Collection<V>)
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.putAll(sampleKey, sampleValueAsCollection);
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("putAll(K, Iterable) succeeded on unmodifiable multimap");
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #putAll(Multimap<K, V>)
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Multimap<K, V> multimap2 = ArrayListMultimap.create();
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multimap2.put(sampleKey, sampleValue);
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.putAll(multimap2);
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("putAll(Multimap<K, V>) succeeded on unmodifiable multimap");
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #remove()
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.remove(sampleKey, sampleValue);
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("remove succeeded on unmodifiable multimap");
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #removeAll()
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.removeAll(sampleKey);
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("removeAll succeeded on unmodifiable multimap");
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #replaceValues()
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.replaceValues(sampleKey, sampleValueAsCollection);
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("replaceValues succeeded on unmodifiable multimap");
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Test #asMap()
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      multimap.asMap().remove(sampleKey);
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("asMap().remove() succeeded on unmodifiable multimap");
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!multimap.isEmpty()) {
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      K presentKey = multimap.keySet().iterator().next();
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        multimap.asMap().get(presentKey).remove(sampleValue);
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("asMap().get().remove() succeeded on unmodifiable multimap");
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (UnsupportedOperationException expected) {
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertMultimapRemainsUnmodified(multimap, originalEntries);
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        multimap.asMap().values().iterator().next().remove(sampleValue);
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("asMap().values().iterator().next().remove() succeeded on " +
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                "unmodifiable multimap");
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (UnsupportedOperationException expected) {
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ((Collection<?>) multimap.asMap().values().toArray()[0]).clear();
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("asMap().values().toArray()[0].clear() succeeded on " +
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                "unmodifiable multimap");
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (UnsupportedOperationException expected) {
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertCollectionIsUnmodifiable(multimap.values(), sampleValue);
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMultimapRemainsUnmodified(multimap, originalEntries);
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> void assertCollectionsAreEquivalent(
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<E> expected, Collection<E> actual) {
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertIteratorsInOrder(expected.iterator(), actual.iterator());
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <K, V> void assertMultimapRemainsUnmodified(
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multimap<K, V> expected, List<Entry<K, V>> actual) {
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertIteratorsInOrder(
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      expected.entries().iterator(), actual.iterator());
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
426