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
193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport static com.google.common.truth.Truth.assertThat;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.CollectionFeature;
220888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.CollectionSize;
230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.MapFeature;
240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
260888a09821a98ac0680fad765217302858e70fa4Paul Duffin
270888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.Test;
280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestCase;
290888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestSuite;
300888a09821a98ac0680fad765217302858e70fa4Paul Duffin
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
350888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Map.Entry;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.RandomAccess;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests for {@code Synchronized#multimap}.
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
460888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic class SynchronizedMultimapTest extends TestCase {
470888a09821a98ac0680fad765217302858e70fa4Paul Duffin
480888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static Test suite() {
490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TestSuite suite = new TestSuite();
500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    suite.addTestSuite(SynchronizedMultimapTest.class);
510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
520888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override
530888a09821a98ac0680fad765217302858e70fa4Paul Duffin        protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
540888a09821a98ac0680fad765217302858e70fa4Paul Duffin          TestMultimap<String, String> inner = new TestMultimap<String, String>();
550888a09821a98ac0680fad765217302858e70fa4Paul Duffin          SetMultimap<String, String> outer = Synchronized.setMultimap(inner, inner.mutex);
560888a09821a98ac0680fad765217302858e70fa4Paul Duffin          for (Entry<String, String> entry : entries) {
570888a09821a98ac0680fad765217302858e70fa4Paul Duffin            outer.put(entry.getKey(), entry.getValue());
580888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
590888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return outer;
600888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
610888a09821a98ac0680fad765217302858e70fa4Paul Duffin      })
620888a09821a98ac0680fad765217302858e70fa4Paul Duffin      .named("Synchronized.setMultimap")
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin      .withFeatures(MapFeature.GENERAL_PURPOSE,
640888a09821a98ac0680fad765217302858e70fa4Paul Duffin          CollectionSize.ANY,
650888a09821a98ac0680fad765217302858e70fa4Paul Duffin          CollectionFeature.SERIALIZABLE,
660888a09821a98ac0680fad765217302858e70fa4Paul Duffin          CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
670888a09821a98ac0680fad765217302858e70fa4Paul Duffin          MapFeature.ALLOWS_NULL_KEYS,
680888a09821a98ac0680fad765217302858e70fa4Paul Duffin          MapFeature.ALLOWS_NULL_VALUES,
690888a09821a98ac0680fad765217302858e70fa4Paul Duffin          MapFeature.ALLOWS_ANY_NULL_QUERIES)
700888a09821a98ac0680fad765217302858e70fa4Paul Duffin      .createTestSuite());
710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return suite;
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
740888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final class TestMultimap<K, V> extends ForwardingSetMultimap<K, V>
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements Serializable {
760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final SetMultimap<K, V> delegate = HashMultimap.create();
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public final Object mutex = new Integer(1); // something Serializable
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected SetMultimap<K, V> delegate() {
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.toString();
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(@Nullable Object o) {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.equals(o);
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.hashCode();
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int size() {
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.size();
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean isEmpty() {
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.isEmpty();
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsKey(@Nullable Object key) {
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.containsKey(key);
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsValue(@Nullable Object value) {
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.containsValue(value);
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsEntry(@Nullable Object key,
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable Object value) {
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.containsEntry(key, value);
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Set<V> get(@Nullable K key) {
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /* TODO: verify that the Collection is also synchronized? */
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.get(key);
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean put(K key, V value) {
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.put(key, value);
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean putAll(@Nullable K key,
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterable<? extends V> values) {
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.putAll(key, values);
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean putAll(Multimap<? extends K, ? extends V> map) {
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.putAll(map);
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Set<V> replaceValues(@Nullable K key,
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Iterable<? extends V> values) {
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.replaceValues(key, values);
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean remove(@Nullable Object key,
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable Object value) {
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.remove(key, value);
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Set<V> removeAll(@Nullable Object key) {
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.removeAll(key);
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super.clear();
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<K> keySet() {
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /* TODO: verify that the Set is also synchronized? */
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.keySet();
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Multiset<K> keys() {
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /* TODO: verify that the Set is also synchronized? */
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.keys();
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> values() {
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /* TODO: verify that the Collection is also synchronized? */
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.values();
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Set<Map.Entry<K, V>> entries() {
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /* TODO: verify that the Collection is also synchronized? */
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.entries();
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<K, Collection<V>> asMap() {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue(Thread.holdsLock(mutex));
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /* TODO: verify that the Map is also synchronized? */
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return super.asMap();
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSynchronizedListMultimap() {
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ListMultimap<String, Integer> multimap
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Multimaps.synchronizedListMultimap(
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            ArrayListMultimap.<String, Integer>create());
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
2073ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(multimap.removeAll("foo")).has().exactly(3, -1, 2, 4, 1).inOrder();
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(multimap.containsKey("foo"));
2093ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(multimap.replaceValues("bar", Arrays.asList(6, 5)))
2100888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .has().exactly(1, 2, 3, 1).inOrder();
2113ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(multimap.get("bar")).has().exactly(6, 5).inOrder();
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSynchronizedSortedSetMultimap() {
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    SortedSetMultimap<String, Integer> multimap
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Multimaps.synchronizedSortedSetMultimap(
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            TreeMultimap.<String, Integer>create());
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
2203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(multimap.removeAll("foo")).has().exactly(-1, 1, 2, 3, 4).inOrder();
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(multimap.containsKey("foo"));
2223ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(multimap.replaceValues("bar", Arrays.asList(6, 5)))
2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .has().exactly(1, 2, 3).inOrder();
2243ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin    assertThat(multimap.get("bar")).has().exactly(5, 6).inOrder();
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSynchronizedArrayListMultimapRandomAccess() {
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ListMultimap<String, Integer> delegate = ArrayListMultimap.create();
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    delegate.put("foo", 1);
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    delegate.put("foo", 3);
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ListMultimap<String, Integer> multimap
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Multimaps.synchronizedListMultimap(delegate);
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(multimap.get("foo") instanceof RandomAccess);
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(multimap.get("bar") instanceof RandomAccess);
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testSynchronizedLinkedListMultimapRandomAccess() {
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ListMultimap<String, Integer> delegate = LinkedListMultimap.create();
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    delegate.put("foo", 1);
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    delegate.put("foo", 3);
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ListMultimap<String, Integer> multimap
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Multimaps.synchronizedListMultimap(delegate);
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(multimap.get("foo") instanceof RandomAccess);
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(multimap.get("bar") instanceof RandomAccess);
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
247