17dd252788645e940eada959bdde927426e2531c9Paul Duffin/*
27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2012 The Guava Authors
37dd252788645e940eada959bdde927426e2531c9Paul Duffin *
47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License.
67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at
77dd252788645e940eada959bdde927426e2531c9Paul Duffin *
87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
97dd252788645e940eada959bdde927426e2531c9Paul Duffin *
107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software
117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and
147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License.
157dd252788645e940eada959bdde927426e2531c9Paul Duffin */
167dd252788645e940eada959bdde927426e2531c9Paul Duffin
177dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.collect.testing.google;
187dd252788645e940eada959bdde927426e2531c9Paul Duffin
197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkArgument;
207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.testing.Helpers.mapEntry;
217dd252788645e940eada959bdde927426e2531c9Paul Duffin
227dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableList;
237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableMultimap;
247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Multimap;
257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Multiset;
267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.AbstractTester;
277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.CollectionTestSuiteBuilder;
287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.DerivedGenerator;
297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
307dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.Helpers;
317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.MapTestSuiteBuilder;
327dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.OneSizeTestContainerGenerator;
337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.PerCollectionSizeTestSuiteBuilder;
347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.SampleElements;
357dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.TestCollectionGenerator;
367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.TestMapGenerator;
377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.TestSubjectGenerator;
387dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.features.CollectionFeature;
390888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.CollectionSize;
407dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.features.Feature;
410888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.ListFeature;
427dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.testing.features.MapFeature;
437dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.SerializableTester;
447dd252788645e940eada959bdde927426e2531c9Paul Duffin
457dd252788645e940eada959bdde927426e2531c9Paul Duffinimport junit.framework.TestSuite;
467dd252788645e940eada959bdde927426e2531c9Paul Duffin
477dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.ArrayList;
487dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collection;
497dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collections;
500888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.EnumSet;
517dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.HashMap;
527dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.HashSet;
537dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Iterator;
547dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.LinkedHashMap;
557dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.List;
567dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map;
577dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map.Entry;
587dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Set;
597dd252788645e940eada959bdde927426e2531c9Paul Duffin
607dd252788645e940eada959bdde927426e2531c9Paul Duffin/**
617dd252788645e940eada959bdde927426e2531c9Paul Duffin * Creates, based on your criteria, a JUnit test suite that exhaustively tests
627dd252788645e940eada959bdde927426e2531c9Paul Duffin * a {@code Multimap} implementation.
637dd252788645e940eada959bdde927426e2531c9Paul Duffin *
647dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Louis Wasserman
657dd252788645e940eada959bdde927426e2531c9Paul Duffin */
667dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic class MultimapTestSuiteBuilder<K, V, M extends Multimap<K, V>> extends
677dd252788645e940eada959bdde927426e2531c9Paul Duffin    PerCollectionSizeTestSuiteBuilder<
687dd252788645e940eada959bdde927426e2531c9Paul Duffin    MultimapTestSuiteBuilder<K, V, M>,
697dd252788645e940eada959bdde927426e2531c9Paul Duffin    TestMultimapGenerator<K, V, M>, M, Map.Entry<K, V>> {
707dd252788645e940eada959bdde927426e2531c9Paul Duffin
717dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static <K, V, M extends Multimap<K, V>> MultimapTestSuiteBuilder<K, V, M> using(
727dd252788645e940eada959bdde927426e2531c9Paul Duffin      TestMultimapGenerator<K, V, M> generator) {
737dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new MultimapTestSuiteBuilder<K, V, M>().usingGenerator(generator);
747dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
757dd252788645e940eada959bdde927426e2531c9Paul Duffin
767dd252788645e940eada959bdde927426e2531c9Paul Duffin  // Class parameters must be raw.
777dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Override
787dd252788645e940eada959bdde927426e2531c9Paul Duffin  protected List<Class<? extends AbstractTester>> getTesters() {
797dd252788645e940eada959bdde927426e2531c9Paul Duffin    return ImmutableList.<Class<? extends AbstractTester>> of(
800888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapAsMapGetTester.class,
810888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapAsMapTester.class,
827dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapSizeTester.class,
830888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapClearTester.class,
847dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapContainsKeyTester.class,
857dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapContainsValueTester.class,
867dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapContainsEntryTester.class,
870888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapEntriesTester.class,
880888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapEqualsTester.class,
897dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapGetTester.class,
900888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapKeySetTester.class,
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapKeysTester.class,
927dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapPutTester.class,
930888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapPutAllMultimapTester.class,
947dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapPutIterableTester.class,
957dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapReplaceValuesTester.class,
967dd252788645e940eada959bdde927426e2531c9Paul Duffin        MultimapRemoveEntryTester.class,
970888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapRemoveAllTester.class,
980888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapToStringTester.class,
990888a09821a98ac0680fad765217302858e70fa4Paul Duffin        MultimapValuesTester.class);
1007dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1017dd252788645e940eada959bdde927426e2531c9Paul Duffin
1027dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Override
1037dd252788645e940eada959bdde927426e2531c9Paul Duffin  protected List<TestSuite> createDerivedSuites(
1047dd252788645e940eada959bdde927426e2531c9Paul Duffin      FeatureSpecificTestSuiteBuilder<
1057dd252788645e940eada959bdde927426e2531c9Paul Duffin      ?,
1067dd252788645e940eada959bdde927426e2531c9Paul Duffin      ? extends OneSizeTestContainerGenerator<M, Map.Entry<K, V>>>
1077dd252788645e940eada959bdde927426e2531c9Paul Duffin      parentBuilder) {
1087dd252788645e940eada959bdde927426e2531c9Paul Duffin    // TODO: Once invariant support is added, supply invariants to each of the
1097dd252788645e940eada959bdde927426e2531c9Paul Duffin    // derived suites, to check that mutations to the derived collections are
1107dd252788645e940eada959bdde927426e2531c9Paul Duffin    // reflected in the underlying map.
1117dd252788645e940eada959bdde927426e2531c9Paul Duffin
1127dd252788645e940eada959bdde927426e2531c9Paul Duffin    List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
1137dd252788645e940eada959bdde927426e2531c9Paul Duffin
1147dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
1157dd252788645e940eada959bdde927426e2531c9Paul Duffin      derivedSuites.add(MultimapTestSuiteBuilder.using(
1167dd252788645e940eada959bdde927426e2531c9Paul Duffin          new ReserializedMultimapGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
1177dd252788645e940eada959bdde927426e2531c9Paul Duffin          .withFeatures(computeReserializedMultimapFeatures(parentBuilder.getFeatures()))
1187dd252788645e940eada959bdde927426e2531c9Paul Duffin          .named(parentBuilder.getName() + " reserialized")
1197dd252788645e940eada959bdde927426e2531c9Paul Duffin          .suppressing(parentBuilder.getSuppressedTests())
1207dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createTestSuite());
1217dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1227dd252788645e940eada959bdde927426e2531c9Paul Duffin
1237dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedSuites.add(MapTestSuiteBuilder.using(
1247dd252788645e940eada959bdde927426e2531c9Paul Duffin        new AsMapGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
1257dd252788645e940eada959bdde927426e2531c9Paul Duffin        .withFeatures(computeAsMapFeatures(parentBuilder.getFeatures()))
1267dd252788645e940eada959bdde927426e2531c9Paul Duffin        .named(parentBuilder.getName() + ".asMap")
1277dd252788645e940eada959bdde927426e2531c9Paul Duffin        .suppressing(parentBuilder.getSuppressedTests())
1287dd252788645e940eada959bdde927426e2531c9Paul Duffin        .createTestSuite());
1297dd252788645e940eada959bdde927426e2531c9Paul Duffin
1307dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedSuites.add(computeEntriesTestSuite(parentBuilder));
1317dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedSuites.add(computeMultimapGetTestSuite(parentBuilder));
1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    derivedSuites.add(computeMultimapAsMapGetTestSuite(parentBuilder));
1337dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedSuites.add(computeKeysTestSuite(parentBuilder));
1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    derivedSuites.add(computeValuesTestSuite(parentBuilder));
1357dd252788645e940eada959bdde927426e2531c9Paul Duffin
1367dd252788645e940eada959bdde927426e2531c9Paul Duffin    return derivedSuites;
1377dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1387dd252788645e940eada959bdde927426e2531c9Paul Duffin
1397dd252788645e940eada959bdde927426e2531c9Paul Duffin  TestSuite computeValuesTestSuite(
1407dd252788645e940eada959bdde927426e2531c9Paul Duffin      FeatureSpecificTestSuiteBuilder<?, ?
1417dd252788645e940eada959bdde927426e2531c9Paul Duffin          extends OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
1427dd252788645e940eada959bdde927426e2531c9Paul Duffin    return CollectionTestSuiteBuilder.using(
1437dd252788645e940eada959bdde927426e2531c9Paul Duffin        new ValuesGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
1447dd252788645e940eada959bdde927426e2531c9Paul Duffin        .withFeatures(computeValuesFeatures(parentBuilder.getFeatures()))
1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .named(parentBuilder.getName() + ".values")
1467dd252788645e940eada959bdde927426e2531c9Paul Duffin        .suppressing(parentBuilder.getSuppressedTests())
1477dd252788645e940eada959bdde927426e2531c9Paul Duffin        .createTestSuite();
1487dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1497dd252788645e940eada959bdde927426e2531c9Paul Duffin
1507dd252788645e940eada959bdde927426e2531c9Paul Duffin  TestSuite computeEntriesTestSuite(
1517dd252788645e940eada959bdde927426e2531c9Paul Duffin      FeatureSpecificTestSuiteBuilder<?, ?
1527dd252788645e940eada959bdde927426e2531c9Paul Duffin          extends OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
1537dd252788645e940eada959bdde927426e2531c9Paul Duffin    return CollectionTestSuiteBuilder.using(
1547dd252788645e940eada959bdde927426e2531c9Paul Duffin        new EntriesGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
1557dd252788645e940eada959bdde927426e2531c9Paul Duffin        .withFeatures(computeEntriesFeatures(parentBuilder.getFeatures()))
1567dd252788645e940eada959bdde927426e2531c9Paul Duffin        .named(parentBuilder.getName() + ".entries")
1577dd252788645e940eada959bdde927426e2531c9Paul Duffin        .suppressing(parentBuilder.getSuppressedTests())
1587dd252788645e940eada959bdde927426e2531c9Paul Duffin        .createTestSuite();
1597dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1607dd252788645e940eada959bdde927426e2531c9Paul Duffin
1617dd252788645e940eada959bdde927426e2531c9Paul Duffin  TestSuite computeMultimapGetTestSuite(
1627dd252788645e940eada959bdde927426e2531c9Paul Duffin      FeatureSpecificTestSuiteBuilder<?, ? extends
1637dd252788645e940eada959bdde927426e2531c9Paul Duffin          OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin    return CollectionTestSuiteBuilder.using(
1657dd252788645e940eada959bdde927426e2531c9Paul Duffin        new MultimapGetGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
1667dd252788645e940eada959bdde927426e2531c9Paul Duffin        .withFeatures(computeMultimapGetFeatures(parentBuilder.getFeatures()))
1677dd252788645e940eada959bdde927426e2531c9Paul Duffin        .named(parentBuilder.getName() + ".get[key]")
1687dd252788645e940eada959bdde927426e2531c9Paul Duffin        .suppressing(parentBuilder.getSuppressedTests())
1697dd252788645e940eada959bdde927426e2531c9Paul Duffin        .createTestSuite();
1707dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1717dd252788645e940eada959bdde927426e2531c9Paul Duffin
1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin  TestSuite computeMultimapAsMapGetTestSuite(
1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin      FeatureSpecificTestSuiteBuilder<?, ? extends
1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin          OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Feature<?>> features = computeMultimapAsMapGetFeatures(parentBuilder.getFeatures());
1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (Collections.disjoint(features, EnumSet.allOf(CollectionSize.class))) {
1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return new TestSuite();
1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } else {
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return CollectionTestSuiteBuilder.using(
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin          new MultimapAsMapGetGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .withFeatures(features)
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .named(parentBuilder.getName() + ".asMap[].get[key]")
1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .suppressing(parentBuilder.getSuppressedTests())
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .createTestSuite();
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1887dd252788645e940eada959bdde927426e2531c9Paul Duffin  TestSuite computeKeysTestSuite(
1897dd252788645e940eada959bdde927426e2531c9Paul Duffin      FeatureSpecificTestSuiteBuilder<?, ? extends
1907dd252788645e940eada959bdde927426e2531c9Paul Duffin          OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
1917dd252788645e940eada959bdde927426e2531c9Paul Duffin    return MultisetTestSuiteBuilder.using(
1927dd252788645e940eada959bdde927426e2531c9Paul Duffin        new KeysGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
1937dd252788645e940eada959bdde927426e2531c9Paul Duffin        .withFeatures(computeKeysFeatures(parentBuilder.getFeatures()))
1947dd252788645e940eada959bdde927426e2531c9Paul Duffin        .named(parentBuilder.getName() + ".keys")
1957dd252788645e940eada959bdde927426e2531c9Paul Duffin        .suppressing(parentBuilder.getSuppressedTests())
1967dd252788645e940eada959bdde927426e2531c9Paul Duffin        .createTestSuite();
1977dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1987dd252788645e940eada959bdde927426e2531c9Paul Duffin
1997dd252788645e940eada959bdde927426e2531c9Paul Duffin  static Set<Feature<?>> computeDerivedCollectionFeatures(Set<Feature<?>> multimapFeatures) {
2007dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
2017dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (!derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
2027dd252788645e940eada959bdde927426e2531c9Paul Duffin      derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
2037dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2047dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (derivedFeatures.remove(MapFeature.SUPPORTS_REMOVE)) {
2057dd252788645e940eada959bdde927426e2531c9Paul Duffin      derivedFeatures.add(CollectionFeature.SUPPORTS_REMOVE);
2067dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2077dd252788645e940eada959bdde927426e2531c9Paul Duffin    return derivedFeatures;
2087dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2097dd252788645e940eada959bdde927426e2531c9Paul Duffin
2107dd252788645e940eada959bdde927426e2531c9Paul Duffin  static Set<Feature<?>> computeEntriesFeatures(
2117dd252788645e940eada959bdde927426e2531c9Paul Duffin      Set<Feature<?>> multimapFeatures) {
2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Feature<?>> result = computeDerivedCollectionFeatures(multimapFeatures);
2130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) {
2140888a09821a98ac0680fad765217302858e70fa4Paul Duffin      result.add(CollectionFeature.ALLOWS_NULL_QUERIES);
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return result;
2177dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2187dd252788645e940eada959bdde927426e2531c9Paul Duffin
2197dd252788645e940eada959bdde927426e2531c9Paul Duffin  static Set<Feature<?>> computeValuesFeatures(
2207dd252788645e940eada959bdde927426e2531c9Paul Duffin      Set<Feature<?>> multimapFeatures) {
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Feature<?>> result = computeDerivedCollectionFeatures(multimapFeatures);
2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) {
2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      result.add(CollectionFeature.ALLOWS_NULL_VALUES);
2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) {
2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin      result.add(CollectionFeature.ALLOWS_NULL_QUERIES);
2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return result;
2297dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2307dd252788645e940eada959bdde927426e2531c9Paul Duffin
2317dd252788645e940eada959bdde927426e2531c9Paul Duffin  static Set<Feature<?>> computeKeysFeatures(
2327dd252788645e940eada959bdde927426e2531c9Paul Duffin      Set<Feature<?>> multimapFeatures) {
2337dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<Feature<?>> result = computeDerivedCollectionFeatures(multimapFeatures);
2347dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) {
2357dd252788645e940eada959bdde927426e2531c9Paul Duffin      result.add(CollectionFeature.ALLOWS_NULL_VALUES);
2367dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) {
2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin      result.add(CollectionFeature.ALLOWS_NULL_QUERIES);
2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2407dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result;
2417dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2427dd252788645e940eada959bdde927426e2531c9Paul Duffin
2437dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static Set<Feature<?>> computeReserializedMultimapFeatures(
2447dd252788645e940eada959bdde927426e2531c9Paul Duffin      Set<Feature<?>> multimapFeatures) {
2457dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
2467dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
2477dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
2487dd252788645e940eada959bdde927426e2531c9Paul Duffin    return derivedFeatures;
2497dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2507dd252788645e940eada959bdde927426e2531c9Paul Duffin
2517dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static Set<Feature<?>> computeAsMapFeatures(
2527dd252788645e940eada959bdde927426e2531c9Paul Duffin      Set<Feature<?>> multimapFeatures) {
2537dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
2547dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedFeatures.remove(MapFeature.GENERAL_PURPOSE);
2557dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedFeatures.remove(MapFeature.SUPPORTS_PUT);
2567dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedFeatures.remove(MapFeature.ALLOWS_NULL_VALUES);
2570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    derivedFeatures.add(MapFeature.ALLOWS_NULL_VALUE_QUERIES);
2587dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedFeatures.add(MapFeature.REJECTS_DUPLICATES_AT_CREATION);
2597dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (!derivedFeatures.contains(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
2607dd252788645e940eada959bdde927426e2531c9Paul Duffin      derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
2617dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2627dd252788645e940eada959bdde927426e2531c9Paul Duffin    return derivedFeatures;
2637dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2647dd252788645e940eada959bdde927426e2531c9Paul Duffin
2657dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final Multimap<Feature<?>, Feature<?>> GET_FEATURE_MAP = ImmutableMultimap
2667dd252788645e940eada959bdde927426e2531c9Paul Duffin      .<Feature<?>, Feature<?>> builder()
2677dd252788645e940eada959bdde927426e2531c9Paul Duffin      .put(
2687dd252788645e940eada959bdde927426e2531c9Paul Duffin          MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
2697dd252788645e940eada959bdde927426e2531c9Paul Duffin          CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION)
2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin      .put(MapFeature.GENERAL_PURPOSE, ListFeature.SUPPORTS_ADD_WITH_INDEX)
2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin      .put(MapFeature.GENERAL_PURPOSE, ListFeature.SUPPORTS_REMOVE_WITH_INDEX)
2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin      .put(MapFeature.GENERAL_PURPOSE, ListFeature.SUPPORTS_SET)
2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin      .put(MapFeature.ALLOWS_NULL_VALUE_QUERIES,
2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin          CollectionFeature.ALLOWS_NULL_QUERIES)
2757dd252788645e940eada959bdde927426e2531c9Paul Duffin      .put(MapFeature.ALLOWS_NULL_VALUES, CollectionFeature.ALLOWS_NULL_VALUES)
2767dd252788645e940eada959bdde927426e2531c9Paul Duffin      .put(MapFeature.SUPPORTS_REMOVE, CollectionFeature.SUPPORTS_REMOVE)
2777dd252788645e940eada959bdde927426e2531c9Paul Duffin      .put(MapFeature.SUPPORTS_PUT, CollectionFeature.SUPPORTS_ADD)
2787dd252788645e940eada959bdde927426e2531c9Paul Duffin      .build();
2797dd252788645e940eada959bdde927426e2531c9Paul Duffin
2807dd252788645e940eada959bdde927426e2531c9Paul Duffin  Set<Feature<?>> computeMultimapGetFeatures(
2817dd252788645e940eada959bdde927426e2531c9Paul Duffin      Set<Feature<?>> multimapFeatures) {
2827dd252788645e940eada959bdde927426e2531c9Paul Duffin    Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
2837dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (Map.Entry<Feature<?>, Feature<?>> entry : GET_FEATURE_MAP.entries()) {
2847dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (derivedFeatures.contains(entry.getKey())) {
2857dd252788645e940eada959bdde927426e2531c9Paul Duffin        derivedFeatures.add(entry.getValue());
2867dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2877dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (derivedFeatures.remove(MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE)) {
2890888a09821a98ac0680fad765217302858e70fa4Paul Duffin      derivedFeatures.add(CollectionFeature.SUPPORTS_ITERATOR_REMOVE);
2900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2917dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (!derivedFeatures.contains(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
2927dd252788645e940eada959bdde927426e2531c9Paul Duffin      derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
2937dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2947dd252788645e940eada959bdde927426e2531c9Paul Duffin    derivedFeatures.removeAll(GET_FEATURE_MAP.keySet());
2957dd252788645e940eada959bdde927426e2531c9Paul Duffin    return derivedFeatures;
2967dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2977dd252788645e940eada959bdde927426e2531c9Paul Duffin
2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin  Set<Feature<?>> computeMultimapAsMapGetFeatures(
2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Set<Feature<?>> multimapFeatures) {
3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Feature<?>> derivedFeatures = Helpers.copyToSet(
3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin        computeMultimapGetFeatures(multimapFeatures));
3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (derivedFeatures.remove(CollectionSize.ANY)) {
3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin      derivedFeatures.addAll(CollectionSize.ANY.getImpliedFeatures());
3040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    derivedFeatures.remove(CollectionSize.ZERO);
3060888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return derivedFeatures;
3070888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3080888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3097dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class AsMapGenerator<K, V, M extends Multimap<K, V>> implements
3107dd252788645e940eada959bdde927426e2531c9Paul Duffin      TestMapGenerator<K, Collection<V>>, DerivedGenerator {
3117dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
3127dd252788645e940eada959bdde927426e2531c9Paul Duffin
3137dd252788645e940eada959bdde927426e2531c9Paul Duffin    public AsMapGenerator(
3147dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
3157dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.multimapGenerator = multimapGenerator;
3167dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3177dd252788645e940eada959bdde927426e2531c9Paul Duffin
3187dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3197dd252788645e940eada959bdde927426e2531c9Paul Duffin    public TestSubjectGenerator<?> getInnerGenerator() {
3207dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator;
3217dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3227dd252788645e940eada959bdde927426e2531c9Paul Duffin
3237dd252788645e940eada959bdde927426e2531c9Paul Duffin    private Collection<V> createCollection(V v) {
3247dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
3257dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createCollection(Collections.singleton(v));
3267dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3277dd252788645e940eada959bdde927426e2531c9Paul Duffin
3287dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3297dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<Entry<K, Collection<V>>> samples() {
3307dd252788645e940eada959bdde927426e2531c9Paul Duffin      SampleElements<K> sampleKeys =
3317dd252788645e940eada959bdde927426e2531c9Paul Duffin          ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys();
3327dd252788645e940eada959bdde927426e2531c9Paul Duffin      SampleElements<V> sampleValues =
3337dd252788645e940eada959bdde927426e2531c9Paul Duffin          ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleValues();
3347dd252788645e940eada959bdde927426e2531c9Paul Duffin      return new SampleElements<Entry<K, Collection<V>>>(
3357dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapEntry(sampleKeys.e0, createCollection(sampleValues.e0)),
3367dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapEntry(sampleKeys.e1, createCollection(sampleValues.e1)),
3377dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapEntry(sampleKeys.e2, createCollection(sampleValues.e2)),
3387dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapEntry(sampleKeys.e3, createCollection(sampleValues.e3)),
3397dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapEntry(sampleKeys.e4, createCollection(sampleValues.e4)));
3407dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3417dd252788645e940eada959bdde927426e2531c9Paul Duffin
3427dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3437dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Map<K, Collection<V>> create(Object... elements) {
3447dd252788645e940eada959bdde927426e2531c9Paul Duffin      Set<K> keySet = new HashSet<K>();
3457dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Map.Entry<K, V>> builder = new ArrayList<Entry<K, V>>();
3467dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Object o : elements) {
3477dd252788645e940eada959bdde927426e2531c9Paul Duffin        Map.Entry<K, Collection<V>> entry = (Entry<K, Collection<V>>) o;
3487dd252788645e940eada959bdde927426e2531c9Paul Duffin        keySet.add(entry.getKey());
3497dd252788645e940eada959bdde927426e2531c9Paul Duffin        for (V v : entry.getValue()) {
3507dd252788645e940eada959bdde927426e2531c9Paul Duffin          builder.add(mapEntry(entry.getKey(), v));
3517dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
3527dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3537dd252788645e940eada959bdde927426e2531c9Paul Duffin      checkArgument(keySet.size() == elements.length, "Duplicate keys");
3547dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.create(builder.toArray()).asMap();
3557dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3567dd252788645e940eada959bdde927426e2531c9Paul Duffin
3577dd252788645e940eada959bdde927426e2531c9Paul Duffin    @SuppressWarnings("unchecked")
3587dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3597dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Entry<K, Collection<V>>[] createArray(int length) {
3607dd252788645e940eada959bdde927426e2531c9Paul Duffin      return new Entry[length];
3617dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3627dd252788645e940eada959bdde927426e2531c9Paul Duffin
3637dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3647dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<Entry<K, Collection<V>>> order(List<Entry<K, Collection<V>>> insertionOrder) {
3657dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<K, Collection<V>> map = new HashMap<K, Collection<V>>();
3667dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Map.Entry<K, V>> builder = new ArrayList<Entry<K, V>>();
3677dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Entry<K, Collection<V>> entry : insertionOrder) {
3687dd252788645e940eada959bdde927426e2531c9Paul Duffin        for (V v : entry.getValue()) {
3697dd252788645e940eada959bdde927426e2531c9Paul Duffin          builder.add(mapEntry(entry.getKey(), v));
3707dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
3717dd252788645e940eada959bdde927426e2531c9Paul Duffin        map.put(entry.getKey(), entry.getValue());
3727dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3737dd252788645e940eada959bdde927426e2531c9Paul Duffin      Iterable<Map.Entry<K, V>> ordered = multimapGenerator.order(builder);
3747dd252788645e940eada959bdde927426e2531c9Paul Duffin      LinkedHashMap<K, Collection<V>> orderedMap = new LinkedHashMap<K, Collection<V>>();
3757dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Map.Entry<K, V> entry : ordered) {
3767dd252788645e940eada959bdde927426e2531c9Paul Duffin        orderedMap.put(entry.getKey(), map.get(entry.getKey()));
3777dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3787dd252788645e940eada959bdde927426e2531c9Paul Duffin      return orderedMap.entrySet();
3797dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3807dd252788645e940eada959bdde927426e2531c9Paul Duffin
3817dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3827dd252788645e940eada959bdde927426e2531c9Paul Duffin    public K[] createKeyArray(int length) {
3837dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
3847dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createKeyArray(length);
3857dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3867dd252788645e940eada959bdde927426e2531c9Paul Duffin
3877dd252788645e940eada959bdde927426e2531c9Paul Duffin    @SuppressWarnings("unchecked")
3887dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3897dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Collection<V>[] createValueArray(int length) {
3907dd252788645e940eada959bdde927426e2531c9Paul Duffin      return new Collection[length];
3917dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3927dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3937dd252788645e940eada959bdde927426e2531c9Paul Duffin
3947dd252788645e940eada959bdde927426e2531c9Paul Duffin  static class EntriesGenerator<K, V, M extends Multimap<K, V>>
3957dd252788645e940eada959bdde927426e2531c9Paul Duffin      implements TestCollectionGenerator<Entry<K, V>>, DerivedGenerator {
3967dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
3977dd252788645e940eada959bdde927426e2531c9Paul Duffin
3987dd252788645e940eada959bdde927426e2531c9Paul Duffin    public EntriesGenerator(
3997dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
4007dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.multimapGenerator = multimapGenerator;
4017dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4027dd252788645e940eada959bdde927426e2531c9Paul Duffin
4037dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4047dd252788645e940eada959bdde927426e2531c9Paul Duffin    public TestSubjectGenerator<?> getInnerGenerator() {
4057dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator;
4067dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4077dd252788645e940eada959bdde927426e2531c9Paul Duffin
4087dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4097dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<Entry<K, V>> samples() {
4107dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.samples();
4117dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4127dd252788645e940eada959bdde927426e2531c9Paul Duffin
4137dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4147dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Collection<Entry<K, V>> create(Object... elements) {
4157dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.create(elements).entries();
4167dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4177dd252788645e940eada959bdde927426e2531c9Paul Duffin
4187dd252788645e940eada959bdde927426e2531c9Paul Duffin    @SuppressWarnings("unchecked")
4197dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4207dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Entry<K, V>[] createArray(int length) {
4217dd252788645e940eada959bdde927426e2531c9Paul Duffin      return new Entry[length];
4227dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4237dd252788645e940eada959bdde927426e2531c9Paul Duffin
4247dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4257dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) {
4267dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.order(insertionOrder);
4277dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4287dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4297dd252788645e940eada959bdde927426e2531c9Paul Duffin
4307dd252788645e940eada959bdde927426e2531c9Paul Duffin  static class ValuesGenerator<K, V, M extends Multimap<K, V>>
4317dd252788645e940eada959bdde927426e2531c9Paul Duffin      implements TestCollectionGenerator<V> {
4327dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
4337dd252788645e940eada959bdde927426e2531c9Paul Duffin
4347dd252788645e940eada959bdde927426e2531c9Paul Duffin    public ValuesGenerator(
4357dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
4367dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.multimapGenerator = multimapGenerator;
4377dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4387dd252788645e940eada959bdde927426e2531c9Paul Duffin
4397dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4407dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<V> samples() {
4417dd252788645e940eada959bdde927426e2531c9Paul Duffin      return
4427dd252788645e940eada959bdde927426e2531c9Paul Duffin          ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleValues();
4437dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4447dd252788645e940eada959bdde927426e2531c9Paul Duffin
4457dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4467dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Collection<V> create(Object... elements) {
4477dd252788645e940eada959bdde927426e2531c9Paul Duffin      K k =
4487dd252788645e940eada959bdde927426e2531c9Paul Duffin          ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys().e0;
4497dd252788645e940eada959bdde927426e2531c9Paul Duffin      Entry<K, V>[] entries = new Entry[elements.length];
4507dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (int i = 0; i < elements.length; i++) {
4517dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries[i] = mapEntry(k, (V) elements[i]);
4527dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
4537dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.create(entries).values();
4547dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4557dd252788645e940eada959bdde927426e2531c9Paul Duffin
4567dd252788645e940eada959bdde927426e2531c9Paul Duffin    @SuppressWarnings("unchecked")
4577dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4587dd252788645e940eada959bdde927426e2531c9Paul Duffin    public V[] createArray(int length) {
4597dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>)
4607dd252788645e940eada959bdde927426e2531c9Paul Duffin          multimapGenerator.getInnerGenerator()).createValueArray(length);
4617dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4627dd252788645e940eada959bdde927426e2531c9Paul Duffin
4637dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4647dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<V> order(List<V> insertionOrder) {
4657dd252788645e940eada959bdde927426e2531c9Paul Duffin      K k =
4667dd252788645e940eada959bdde927426e2531c9Paul Duffin          ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys().e0;
4677dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
4687dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (V v : insertionOrder) {
4697dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries.add(mapEntry(k, v));
4707dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
4717dd252788645e940eada959bdde927426e2531c9Paul Duffin      Iterable<Entry<K, V>> ordered = multimapGenerator.order(entries);
4727dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<V> orderedValues = new ArrayList<V>();
4737dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Entry<K, V> entry : ordered) {
4747dd252788645e940eada959bdde927426e2531c9Paul Duffin        orderedValues.add(entry.getValue());
4757dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
4767dd252788645e940eada959bdde927426e2531c9Paul Duffin      return orderedValues;
4777dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4787dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4797dd252788645e940eada959bdde927426e2531c9Paul Duffin
4807dd252788645e940eada959bdde927426e2531c9Paul Duffin  static class KeysGenerator<K, V, M extends Multimap<K, V>> implements
4817dd252788645e940eada959bdde927426e2531c9Paul Duffin      TestMultisetGenerator<K>, DerivedGenerator {
4827dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
4837dd252788645e940eada959bdde927426e2531c9Paul Duffin
4847dd252788645e940eada959bdde927426e2531c9Paul Duffin    public KeysGenerator(
4857dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
4867dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.multimapGenerator = multimapGenerator;
4877dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4887dd252788645e940eada959bdde927426e2531c9Paul Duffin
4897dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4907dd252788645e940eada959bdde927426e2531c9Paul Duffin    public TestSubjectGenerator<?> getInnerGenerator() {
4917dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator;
4927dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4937dd252788645e940eada959bdde927426e2531c9Paul Duffin
4947dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
4957dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<K> samples() {
4967dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys();
4977dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4987dd252788645e940eada959bdde927426e2531c9Paul Duffin
4997dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5007dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Multiset<K> create(Object... elements) {
5017dd252788645e940eada959bdde927426e2531c9Paul Duffin      /*
5027dd252788645e940eada959bdde927426e2531c9Paul Duffin       * This is nasty and complicated, but it's the only way to make sure keys get mapped to enough
5037dd252788645e940eada959bdde927426e2531c9Paul Duffin       * distinct values.
5047dd252788645e940eada959bdde927426e2531c9Paul Duffin       */
5057dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map.Entry[] entries = new Map.Entry[elements.length];
5067dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<K, Iterator<V>> valueIterators = new HashMap<K, Iterator<V>>();
5077dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (int i = 0; i < elements.length; i++) {
5087dd252788645e940eada959bdde927426e2531c9Paul Duffin        @SuppressWarnings("unchecked")
5097dd252788645e940eada959bdde927426e2531c9Paul Duffin        K key = (K) elements[i];
5107dd252788645e940eada959bdde927426e2531c9Paul Duffin
5117dd252788645e940eada959bdde927426e2531c9Paul Duffin        Iterator<V> valueItr = valueIterators.get(key);
5127dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (valueItr == null) {
5137dd252788645e940eada959bdde927426e2531c9Paul Duffin          valueIterators.put(key, valueItr = sampleValuesIterator());
5147dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
5157dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries[i] = mapEntry((K) elements[i], valueItr.next());
5167dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5177dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.create(entries).keys();
5187dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5197dd252788645e940eada959bdde927426e2531c9Paul Duffin
5207dd252788645e940eada959bdde927426e2531c9Paul Duffin    private Iterator<V> sampleValuesIterator() {
5217dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator
5227dd252788645e940eada959bdde927426e2531c9Paul Duffin          .getInnerGenerator()).sampleValues().iterator();
5237dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5247dd252788645e940eada959bdde927426e2531c9Paul Duffin
5257dd252788645e940eada959bdde927426e2531c9Paul Duffin    @SuppressWarnings("unchecked")
5267dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5277dd252788645e940eada959bdde927426e2531c9Paul Duffin    public K[] createArray(int length) {
5287dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>)
5297dd252788645e940eada959bdde927426e2531c9Paul Duffin          multimapGenerator.getInnerGenerator()).createKeyArray(length);
5307dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5317dd252788645e940eada959bdde927426e2531c9Paul Duffin
5327dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5337dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<K> order(List<K> insertionOrder) {
5347dd252788645e940eada959bdde927426e2531c9Paul Duffin      Iterator<V> valueIter = sampleValuesIterator();
5357dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
5367dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (K k : insertionOrder) {
5377dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries.add(mapEntry(k, valueIter.next()));
5387dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5397dd252788645e940eada959bdde927426e2531c9Paul Duffin      Iterable<Entry<K, V>> ordered = multimapGenerator.order(entries);
5407dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<K> orderedValues = new ArrayList<K>();
5417dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Entry<K, V> entry : ordered) {
5427dd252788645e940eada959bdde927426e2531c9Paul Duffin        orderedValues.add(entry.getKey());
5437dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5447dd252788645e940eada959bdde927426e2531c9Paul Duffin      return orderedValues;
5457dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5467dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5477dd252788645e940eada959bdde927426e2531c9Paul Duffin
5487dd252788645e940eada959bdde927426e2531c9Paul Duffin  static class MultimapGetGenerator<K, V, M extends Multimap<K, V>>
5497dd252788645e940eada959bdde927426e2531c9Paul Duffin      implements TestCollectionGenerator<V> {
5500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
5517dd252788645e940eada959bdde927426e2531c9Paul Duffin
5527dd252788645e940eada959bdde927426e2531c9Paul Duffin    public MultimapGetGenerator(
5537dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<
5547dd252788645e940eada959bdde927426e2531c9Paul Duffin        M, Map.Entry<K, V>> multimapGenerator) {
5557dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.multimapGenerator = multimapGenerator;
5567dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5577dd252788645e940eada959bdde927426e2531c9Paul Duffin
5587dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5597dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<V> samples() {
5607dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
5617dd252788645e940eada959bdde927426e2531c9Paul Duffin          .sampleValues();
5627dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5637dd252788645e940eada959bdde927426e2531c9Paul Duffin
5647dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5657dd252788645e940eada959bdde927426e2531c9Paul Duffin    public V[] createArray(int length) {
5667dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
5677dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createValueArray(length);
5687dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5697dd252788645e940eada959bdde927426e2531c9Paul Duffin
5707dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5717dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<V> order(List<V> insertionOrder) {
5727dd252788645e940eada959bdde927426e2531c9Paul Duffin      K k = ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
5737dd252788645e940eada959bdde927426e2531c9Paul Duffin          .sampleKeys().e0;
5747dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
5757dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (V v : insertionOrder) {
5767dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries.add(mapEntry(k, v));
5777dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5787dd252788645e940eada959bdde927426e2531c9Paul Duffin      Iterable<Entry<K, V>> orderedEntries = multimapGenerator.order(entries);
5797dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<V> values = new ArrayList<V>();
5807dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Entry<K, V> entry : orderedEntries) {
5817dd252788645e940eada959bdde927426e2531c9Paul Duffin        values.add(entry.getValue());
5827dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5837dd252788645e940eada959bdde927426e2531c9Paul Duffin      return values;
5847dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5857dd252788645e940eada959bdde927426e2531c9Paul Duffin
5867dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5877dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Collection<V> create(Object... elements) {
5887dd252788645e940eada959bdde927426e2531c9Paul Duffin      Entry<K, V>[] array = multimapGenerator.createArray(elements.length);
5897dd252788645e940eada959bdde927426e2531c9Paul Duffin      K k = ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
5907dd252788645e940eada959bdde927426e2531c9Paul Duffin          .sampleKeys().e0;
5917dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (int i = 0; i < elements.length; i++) {
5927dd252788645e940eada959bdde927426e2531c9Paul Duffin        array[i] = mapEntry(k, (V) elements[i]);
5937dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5947dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.create(array).get(k);
5957dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5967dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5977dd252788645e940eada959bdde927426e2531c9Paul Duffin
5980888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static class MultimapAsMapGetGenerator<K, V, M extends Multimap<K, V>>
5990888a09821a98ac0680fad765217302858e70fa4Paul Duffin      extends MultimapGetGenerator<K, V, M> {
6000888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public MultimapAsMapGetGenerator(
6020888a09821a98ac0680fad765217302858e70fa4Paul Duffin        OneSizeTestContainerGenerator<
6030888a09821a98ac0680fad765217302858e70fa4Paul Duffin        M, Map.Entry<K, V>> multimapGenerator) {
6040888a09821a98ac0680fad765217302858e70fa4Paul Duffin      super(multimapGenerator);
6050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
6060888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
6080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Collection<V> create(Object... elements) {
6090888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Entry<K, V>[] array = multimapGenerator.createArray(elements.length);
6100888a09821a98ac0680fad765217302858e70fa4Paul Duffin      K k = ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
6110888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .sampleKeys().e0;
6120888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < elements.length; i++) {
6130888a09821a98ac0680fad765217302858e70fa4Paul Duffin        array[i] = mapEntry(k, (V) elements[i]);
6140888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
6150888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return multimapGenerator.create(array).asMap().get(k);
6160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
6170888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6180888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6197dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static class ReserializedMultimapGenerator<K, V, M extends Multimap<K, V>>
6207dd252788645e940eada959bdde927426e2531c9Paul Duffin      implements TestMultimapGenerator<K, V, M> {
6217dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
6227dd252788645e940eada959bdde927426e2531c9Paul Duffin
6237dd252788645e940eada959bdde927426e2531c9Paul Duffin    public ReserializedMultimapGenerator(
6247dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<
6257dd252788645e940eada959bdde927426e2531c9Paul Duffin        M, Map.Entry<K, V>> multimapGenerator) {
6267dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.multimapGenerator = multimapGenerator;
6277dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6287dd252788645e940eada959bdde927426e2531c9Paul Duffin
6297dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6307dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<Map.Entry<K, V>> samples() {
6317dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.samples();
6327dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6337dd252788645e940eada959bdde927426e2531c9Paul Duffin
6347dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6357dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Map.Entry<K, V>[] createArray(int length) {
6367dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.createArray(length);
6377dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6387dd252788645e940eada959bdde927426e2531c9Paul Duffin
6397dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6407dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<Map.Entry<K, V>> order(
6417dd252788645e940eada959bdde927426e2531c9Paul Duffin        List<Map.Entry<K, V>> insertionOrder) {
6427dd252788645e940eada959bdde927426e2531c9Paul Duffin      return multimapGenerator.order(insertionOrder);
6437dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6447dd252788645e940eada959bdde927426e2531c9Paul Duffin
6457dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6467dd252788645e940eada959bdde927426e2531c9Paul Duffin    public M create(Object... elements) {
6477dd252788645e940eada959bdde927426e2531c9Paul Duffin      return SerializableTester.reserialize(((TestMultimapGenerator<K, V, M>) multimapGenerator
6487dd252788645e940eada959bdde927426e2531c9Paul Duffin          .getInnerGenerator()).create(elements));
6497dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6507dd252788645e940eada959bdde927426e2531c9Paul Duffin
6517dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6527dd252788645e940eada959bdde927426e2531c9Paul Duffin    public K[] createKeyArray(int length) {
6537dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
6547dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createKeyArray(length);
6557dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6567dd252788645e940eada959bdde927426e2531c9Paul Duffin
6577dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6587dd252788645e940eada959bdde927426e2531c9Paul Duffin    public V[] createValueArray(int length) {
6597dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
6607dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createValueArray(length);
6617dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6627dd252788645e940eada959bdde927426e2531c9Paul Duffin
6637dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6647dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<K> sampleKeys() {
6657dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
6667dd252788645e940eada959bdde927426e2531c9Paul Duffin          .sampleKeys();
6677dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6687dd252788645e940eada959bdde927426e2531c9Paul Duffin
6697dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6707dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<V> sampleValues() {
6717dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
6727dd252788645e940eada959bdde927426e2531c9Paul Duffin          .sampleValues();
6737dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6747dd252788645e940eada959bdde927426e2531c9Paul Duffin
6757dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
6767dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Collection<V> createCollection(Iterable<? extends V> values) {
6777dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
6787dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createCollection(values);
6797dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6807dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6817dd252788645e940eada959bdde927426e2531c9Paul Duffin}
682