17dd252788645e940eada959bdde927426e2531c9Paul Duffin/*
27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2008 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;
187dd252788645e940eada959bdde927426e2531c9Paul Duffin
197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.testing.Helpers.castOrCopyToList;
207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.testing.Helpers.equal;
217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.testing.Helpers.mapEntry;
227dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static java.util.Collections.sort;
237dd252788645e940eada959bdde927426e2531c9Paul Duffin
247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtCompatible;
257dd252788645e940eada959bdde927426e2531c9Paul Duffin
267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.ArrayList;
277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Arrays;
287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collection;
297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collections;
307dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Comparator;
317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.List;
327dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map;
337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map.Entry;
347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Set;
357dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.SortedMap;
360888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.SortedSet;
377dd252788645e940eada959bdde927426e2531c9Paul Duffin
387dd252788645e940eada959bdde927426e2531c9Paul Duffin/**
397dd252788645e940eada959bdde927426e2531c9Paul Duffin * Derived suite generators, split out of the suite builders so that they are available to GWT.
407dd252788645e940eada959bdde927426e2531c9Paul Duffin *
417dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author George van den Driessche
427dd252788645e940eada959bdde927426e2531c9Paul Duffin */
437dd252788645e940eada959bdde927426e2531c9Paul Duffin@GwtCompatible
447dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic final class DerivedCollectionGenerators {
457dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class MapEntrySetGenerator<K, V>
467dd252788645e940eada959bdde927426e2531c9Paul Duffin      implements TestSetGenerator<Map.Entry<K, V>>, DerivedGenerator {
477dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
487dd252788645e940eada959bdde927426e2531c9Paul Duffin        mapGenerator;
497dd252788645e940eada959bdde927426e2531c9Paul Duffin
507dd252788645e940eada959bdde927426e2531c9Paul Duffin    public MapEntrySetGenerator(
517dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<
527dd252788645e940eada959bdde927426e2531c9Paul Duffin            Map<K, V>, Map.Entry<K, V>> mapGenerator) {
537dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.mapGenerator = mapGenerator;
547dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
557dd252788645e940eada959bdde927426e2531c9Paul Duffin
567dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
577dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<Map.Entry<K, V>> samples() {
587dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator.samples();
597dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
607dd252788645e940eada959bdde927426e2531c9Paul Duffin
617dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
627dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Set<Map.Entry<K, V>> create(Object... elements) {
637dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator.create(elements).entrySet();
647dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
657dd252788645e940eada959bdde927426e2531c9Paul Duffin
667dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
677dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Map.Entry<K, V>[] createArray(int length) {
687dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator.createArray(length);
697dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
707dd252788645e940eada959bdde927426e2531c9Paul Duffin
717dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
727dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<Map.Entry<K, V>> order(
737dd252788645e940eada959bdde927426e2531c9Paul Duffin        List<Map.Entry<K, V>> insertionOrder) {
747dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator.order(insertionOrder);
757dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
767dd252788645e940eada959bdde927426e2531c9Paul Duffin
770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
787dd252788645e940eada959bdde927426e2531c9Paul Duffin    public OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>> getInnerGenerator() {
797dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator;
807dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
817dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
827dd252788645e940eada959bdde927426e2531c9Paul Duffin
837dd252788645e940eada959bdde927426e2531c9Paul Duffin  // TODO: investigate some API changes to SampleElements that would tidy up
847dd252788645e940eada959bdde927426e2531c9Paul Duffin  // parts of the following classes.
857dd252788645e940eada959bdde927426e2531c9Paul Duffin
860888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static <K, V> TestSetGenerator<K> keySetGenerator(
870888a09821a98ac0680fad765217302858e70fa4Paul Duffin      OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>> mapGenerator) {
880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TestContainerGenerator<Map<K, V>, Entry<K, V>> generator = mapGenerator.getInnerGenerator();
890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (generator instanceof TestSortedMapGenerator
900888a09821a98ac0680fad765217302858e70fa4Paul Duffin        && ((TestSortedMapGenerator<K, V>) generator).create().keySet() instanceof SortedSet) {
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return new MapSortedKeySetGenerator<K, V>(mapGenerator);
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } else {
930888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return new MapKeySetGenerator<K, V>(mapGenerator);
940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
950888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
960888a09821a98ac0680fad765217302858e70fa4Paul Duffin
977dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class MapKeySetGenerator<K, V>
987dd252788645e940eada959bdde927426e2531c9Paul Duffin      implements TestSetGenerator<K>, DerivedGenerator {
997dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
1007dd252788645e940eada959bdde927426e2531c9Paul Duffin        mapGenerator;
1017dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final SampleElements<K> samples;
1027dd252788645e940eada959bdde927426e2531c9Paul Duffin
1037dd252788645e940eada959bdde927426e2531c9Paul Duffin    public MapKeySetGenerator(
1047dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
1057dd252788645e940eada959bdde927426e2531c9Paul Duffin            mapGenerator) {
1067dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.mapGenerator = mapGenerator;
1077dd252788645e940eada959bdde927426e2531c9Paul Duffin      final SampleElements<Map.Entry<K, V>> mapSamples =
1087dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.mapGenerator.samples();
1097dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.samples = new SampleElements<K>(
1107dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e0.getKey(),
1117dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e1.getKey(),
1127dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e2.getKey(),
1137dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e3.getKey(),
1147dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e4.getKey());
1157dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1167dd252788645e940eada959bdde927426e2531c9Paul Duffin
1177dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
1187dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<K> samples() {
1197dd252788645e940eada959bdde927426e2531c9Paul Duffin      return samples;
1207dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1217dd252788645e940eada959bdde927426e2531c9Paul Duffin
1227dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
1237dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Set<K> create(Object... elements) {
1247dd252788645e940eada959bdde927426e2531c9Paul Duffin      @SuppressWarnings("unchecked")
1257dd252788645e940eada959bdde927426e2531c9Paul Duffin      K[] keysArray = (K[]) elements;
1267dd252788645e940eada959bdde927426e2531c9Paul Duffin
1277dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Start with a suitably shaped collection of entries
1287dd252788645e940eada959bdde927426e2531c9Paul Duffin      Collection<Map.Entry<K, V>> originalEntries =
1297dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapGenerator.getSampleElements(elements.length);
1307dd252788645e940eada959bdde927426e2531c9Paul Duffin
1317dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Create a copy of that, with the desired value for each key
1327dd252788645e940eada959bdde927426e2531c9Paul Duffin      Collection<Map.Entry<K, V>> entries =
1337dd252788645e940eada959bdde927426e2531c9Paul Duffin          new ArrayList<Entry<K, V>>(elements.length);
1347dd252788645e940eada959bdde927426e2531c9Paul Duffin      int i = 0;
1357dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Map.Entry<K, V> entry : originalEntries) {
1367dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries.add(Helpers.mapEntry(keysArray[i++], entry.getValue()));
1377dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1387dd252788645e940eada959bdde927426e2531c9Paul Duffin
1397dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator.create(entries.toArray()).keySet();
1407dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1417dd252788645e940eada959bdde927426e2531c9Paul Duffin
1427dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
1437dd252788645e940eada959bdde927426e2531c9Paul Duffin    public K[] createArray(int length) {
1447dd252788645e940eada959bdde927426e2531c9Paul Duffin      // TODO: with appropriate refactoring of OneSizeGenerator, we can perhaps
1457dd252788645e940eada959bdde927426e2531c9Paul Duffin      // tidy this up and get rid of the casts here and in
1467dd252788645e940eada959bdde927426e2531c9Paul Duffin      // MapValueCollectionGenerator.
1477dd252788645e940eada959bdde927426e2531c9Paul Duffin
1487dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator())
1497dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createKeyArray(length);
1507dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1517dd252788645e940eada959bdde927426e2531c9Paul Duffin
1527dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
1537dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<K> order(List<K> insertionOrder) {
1547dd252788645e940eada959bdde927426e2531c9Paul Duffin      V v = ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator()).samples().e0.getValue();
1557dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
1567dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (K element : insertionOrder) {
1577dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries.add(mapEntry(element, v));
1587dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1597dd252788645e940eada959bdde927426e2531c9Paul Duffin
1607dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<K> keys = new ArrayList<K>();
1617dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Entry<K, V> entry : mapGenerator.order(entries)) {
1627dd252788645e940eada959bdde927426e2531c9Paul Duffin        keys.add(entry.getKey());
1637dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin      return keys;
1657dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1667dd252788645e940eada959bdde927426e2531c9Paul Duffin
1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1687dd252788645e940eada959bdde927426e2531c9Paul Duffin    public OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>> getInnerGenerator() {
1697dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator;
1707dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1717dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static class MapSortedKeySetGenerator<K, V> extends MapKeySetGenerator<K, V>
1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin      implements TestSortedSetGenerator<K>, DerivedGenerator {
1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private final TestSortedMapGenerator<K, V> delegate;
1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public MapSortedKeySetGenerator(
1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin        OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>> mapGenerator) {
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin      super(mapGenerator);
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.delegate = (TestSortedMapGenerator<K, V>) mapGenerator.getInnerGenerator();
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public SortedSet<K> create(Object... elements) {
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return (SortedSet<K>) super.create(elements);
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public K belowSamplesLesser() {
1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.belowSamplesLesser().getKey();
1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public K belowSamplesGreater() {
1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.belowSamplesGreater().getKey();
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public K aboveSamplesLesser() {
2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.aboveSamplesLesser().getKey();
2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public K aboveSamplesGreater() {
2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.aboveSamplesGreater().getKey();
2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2097dd252788645e940eada959bdde927426e2531c9Paul Duffin
2107dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class MapValueCollectionGenerator<K, V>
2117dd252788645e940eada959bdde927426e2531c9Paul Duffin      implements TestCollectionGenerator<V>, DerivedGenerator {
2127dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
2137dd252788645e940eada959bdde927426e2531c9Paul Duffin        mapGenerator;
2147dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final SampleElements<V> samples;
2157dd252788645e940eada959bdde927426e2531c9Paul Duffin
2167dd252788645e940eada959bdde927426e2531c9Paul Duffin    public MapValueCollectionGenerator(
2177dd252788645e940eada959bdde927426e2531c9Paul Duffin        OneSizeTestContainerGenerator<
2187dd252788645e940eada959bdde927426e2531c9Paul Duffin            Map<K, V>, Map.Entry<K, V>> mapGenerator) {
2197dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.mapGenerator = mapGenerator;
2207dd252788645e940eada959bdde927426e2531c9Paul Duffin      final SampleElements<Map.Entry<K, V>> mapSamples =
2217dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.mapGenerator.samples();
2227dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.samples = new SampleElements<V>(
2237dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e0.getValue(),
2247dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e1.getValue(),
2257dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e2.getValue(),
2267dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e3.getValue(),
2277dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapSamples.e4.getValue());
2287dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2297dd252788645e940eada959bdde927426e2531c9Paul Duffin
2307dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
2317dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<V> samples() {
2327dd252788645e940eada959bdde927426e2531c9Paul Duffin      return samples;
2337dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2347dd252788645e940eada959bdde927426e2531c9Paul Duffin
2357dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
2367dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Collection<V> create(Object... elements) {
2377dd252788645e940eada959bdde927426e2531c9Paul Duffin      @SuppressWarnings("unchecked")
2387dd252788645e940eada959bdde927426e2531c9Paul Duffin      V[] valuesArray = (V[]) elements;
2397dd252788645e940eada959bdde927426e2531c9Paul Duffin
2407dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Start with a suitably shaped collection of entries
2417dd252788645e940eada959bdde927426e2531c9Paul Duffin      Collection<Map.Entry<K, V>> originalEntries =
2427dd252788645e940eada959bdde927426e2531c9Paul Duffin          mapGenerator.getSampleElements(elements.length);
2437dd252788645e940eada959bdde927426e2531c9Paul Duffin
2447dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Create a copy of that, with the desired value for each value
2457dd252788645e940eada959bdde927426e2531c9Paul Duffin      Collection<Map.Entry<K, V>> entries =
2467dd252788645e940eada959bdde927426e2531c9Paul Duffin          new ArrayList<Entry<K, V>>(elements.length);
2477dd252788645e940eada959bdde927426e2531c9Paul Duffin      int i = 0;
2487dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (Map.Entry<K, V> entry : originalEntries) {
2497dd252788645e940eada959bdde927426e2531c9Paul Duffin        entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
2507dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2517dd252788645e940eada959bdde927426e2531c9Paul Duffin
2527dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator.create(entries.toArray()).values();
2537dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2547dd252788645e940eada959bdde927426e2531c9Paul Duffin
2557dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
2567dd252788645e940eada959bdde927426e2531c9Paul Duffin    public V[] createArray(int length) {
2577dd252788645e940eada959bdde927426e2531c9Paul Duffin      //noinspection UnnecessaryLocalVariable
2587dd252788645e940eada959bdde927426e2531c9Paul Duffin      final V[] vs = ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator())
2597dd252788645e940eada959bdde927426e2531c9Paul Duffin          .createValueArray(length);
2607dd252788645e940eada959bdde927426e2531c9Paul Duffin      return vs;
2617dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2627dd252788645e940eada959bdde927426e2531c9Paul Duffin
2637dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
2647dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<V> order(List<V> insertionOrder) {
2657dd252788645e940eada959bdde927426e2531c9Paul Duffin      final List<Entry<K, V>> orderedEntries =
2667dd252788645e940eada959bdde927426e2531c9Paul Duffin          castOrCopyToList(mapGenerator.order(castOrCopyToList(
2677dd252788645e940eada959bdde927426e2531c9Paul Duffin              mapGenerator.getSampleElements(5))));
2687dd252788645e940eada959bdde927426e2531c9Paul Duffin      sort(insertionOrder, new Comparator<V>() {
2697dd252788645e940eada959bdde927426e2531c9Paul Duffin        @Override public int compare(V left, V right) {
2707dd252788645e940eada959bdde927426e2531c9Paul Duffin          // The indexes are small enough for the subtraction trick to be safe.
2717dd252788645e940eada959bdde927426e2531c9Paul Duffin          return indexOfEntryWithValue(left) - indexOfEntryWithValue(right);
2727dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
2737dd252788645e940eada959bdde927426e2531c9Paul Duffin
2747dd252788645e940eada959bdde927426e2531c9Paul Duffin        int indexOfEntryWithValue(V value) {
2757dd252788645e940eada959bdde927426e2531c9Paul Duffin          for (int i = 0; i < orderedEntries.size(); i++) {
2767dd252788645e940eada959bdde927426e2531c9Paul Duffin            if (equal(orderedEntries.get(i).getValue(), value)) {
2777dd252788645e940eada959bdde927426e2531c9Paul Duffin              return i;
2787dd252788645e940eada959bdde927426e2531c9Paul Duffin            }
2797dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
2807dd252788645e940eada959bdde927426e2531c9Paul Duffin          throw new IllegalArgumentException("Map.values generator can order only sample values");
2817dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
2827dd252788645e940eada959bdde927426e2531c9Paul Duffin      });
2837dd252788645e940eada959bdde927426e2531c9Paul Duffin      return insertionOrder;
2847dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2857dd252788645e940eada959bdde927426e2531c9Paul Duffin
2860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2877dd252788645e940eada959bdde927426e2531c9Paul Duffin    public OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>> getInnerGenerator() {
2887dd252788645e940eada959bdde927426e2531c9Paul Duffin      return mapGenerator;
2897dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2907dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2917dd252788645e940eada959bdde927426e2531c9Paul Duffin
2927dd252788645e940eada959bdde927426e2531c9Paul Duffin  // TODO(cpovirk): could something like this be used elsewhere, e.g., ReserializedListGenerator?
2937dd252788645e940eada959bdde927426e2531c9Paul Duffin  static class ForwardingTestMapGenerator<K, V> implements TestMapGenerator<K, V> {
2947dd252788645e940eada959bdde927426e2531c9Paul Duffin    TestMapGenerator<K, V> delegate;
2957dd252788645e940eada959bdde927426e2531c9Paul Duffin
2967dd252788645e940eada959bdde927426e2531c9Paul Duffin    ForwardingTestMapGenerator(TestMapGenerator<K, V> delegate) {
2977dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.delegate = delegate;
2987dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2997dd252788645e940eada959bdde927426e2531c9Paul Duffin
3007dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3017dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) {
3027dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.order(insertionOrder);
3037dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3047dd252788645e940eada959bdde927426e2531c9Paul Duffin
3057dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3067dd252788645e940eada959bdde927426e2531c9Paul Duffin    public K[] createKeyArray(int length) {
3077dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.createKeyArray(length);
3087dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3097dd252788645e940eada959bdde927426e2531c9Paul Duffin
3107dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3117dd252788645e940eada959bdde927426e2531c9Paul Duffin    public V[] createValueArray(int length) {
3127dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.createValueArray(length);
3137dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3147dd252788645e940eada959bdde927426e2531c9Paul Duffin
3157dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3167dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SampleElements<Entry<K, V>> samples() {
3177dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.samples();
3187dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3197dd252788645e940eada959bdde927426e2531c9Paul Duffin
3207dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3217dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Map<K, V> create(Object... elements) {
3227dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.create(elements);
3237dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3247dd252788645e940eada959bdde927426e2531c9Paul Duffin
3257dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
3267dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Entry<K, V>[] createArray(int length) {
3277dd252788645e940eada959bdde927426e2531c9Paul Duffin      return delegate.createArray(length);
3287dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3297dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3307dd252788645e940eada959bdde927426e2531c9Paul Duffin
3317dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
3327dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Two bounds (from and to) define how to build a subMap.
3337dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
3347dd252788645e940eada959bdde927426e2531c9Paul Duffin  public enum Bound {
3357dd252788645e940eada959bdde927426e2531c9Paul Duffin    INCLUSIVE,
3367dd252788645e940eada959bdde927426e2531c9Paul Duffin    EXCLUSIVE,
3377dd252788645e940eada959bdde927426e2531c9Paul Duffin    NO_BOUND;
3387dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3390888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static class SortedSetSubsetTestSetGenerator<E>
3410888a09821a98ac0680fad765217302858e70fa4Paul Duffin      implements TestSortedSetGenerator<E> {
3420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final Bound to;
3430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final Bound from;
3440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final E firstInclusive;
3450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final E lastInclusive;
3460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private final Comparator<? super E> comparator;
3470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private final TestSortedSetGenerator<E> delegate;
3480888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public SortedSetSubsetTestSetGenerator(
3500888a09821a98ac0680fad765217302858e70fa4Paul Duffin        TestSortedSetGenerator<E> delegate, Bound to, Bound from) {
3510888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.to = to;
3520888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.from = from;
3530888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.delegate = delegate;
3540888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3550888a09821a98ac0680fad765217302858e70fa4Paul Duffin      SortedSet<E> emptySet = delegate.create();
3560888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.comparator = emptySet.comparator();
3570888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3580888a09821a98ac0680fad765217302858e70fa4Paul Duffin      SampleElements<E> samples = delegate.samples();
3590888a09821a98ac0680fad765217302858e70fa4Paul Duffin      List<E> samplesList = new ArrayList<E>(samples.asList());
3600888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Collections.sort(samplesList, comparator);
3610888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.firstInclusive = samplesList.get(0);
3620888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.lastInclusive = samplesList.get(samplesList.size() - 1);
3630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3640888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public final TestSortedSetGenerator<E> getInnerGenerator() {
3660888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate;
3670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3680888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public final Bound getTo() {
3700888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return to;
3710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3720888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public final Bound getFrom() {
3740888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return from;
3750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3760888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
3780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public SampleElements<E> samples() {
3790888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.samples();
3800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3810888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
3830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public E[] createArray(int length) {
3840888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.createArray(length);
3850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3860888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
3880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Iterable<E> order(List<E> insertionOrder) {
3890888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return delegate.order(insertionOrder);
3900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3910888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
3930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public SortedSet<E> create(Object... elements) {
3940888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // set generators must pass SampleElements values
3950888a09821a98ac0680fad765217302858e70fa4Paul Duffin      List<E> normalValues = (List) Arrays.asList(elements);
3960888a09821a98ac0680fad765217302858e70fa4Paul Duffin      List<E> extremeValues = new ArrayList<E>();
3970888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3980888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // nulls are usually out of bounds for a subset, so ban them altogether
3990888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (Object o : elements) {
4000888a09821a98ac0680fad765217302858e70fa4Paul Duffin        if (o == null) {
4010888a09821a98ac0680fad765217302858e70fa4Paul Duffin          throw new NullPointerException();
4020888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
4030888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
4040888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4050888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // prepare extreme values to be filtered out of view
4060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      E firstExclusive = delegate.belowSamplesGreater();
4070888a09821a98ac0680fad765217302858e70fa4Paul Duffin      E lastExclusive = delegate.aboveSamplesLesser();
4080888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (from != Bound.NO_BOUND) {
4090888a09821a98ac0680fad765217302858e70fa4Paul Duffin        extremeValues.add(delegate.belowSamplesLesser());
4100888a09821a98ac0680fad765217302858e70fa4Paul Duffin        extremeValues.add(delegate.belowSamplesGreater());
4110888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
4120888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (to != Bound.NO_BOUND) {
4130888a09821a98ac0680fad765217302858e70fa4Paul Duffin        extremeValues.add(delegate.aboveSamplesLesser());
4140888a09821a98ac0680fad765217302858e70fa4Paul Duffin        extremeValues.add(delegate.aboveSamplesGreater());
4150888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
4160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // the regular values should be visible after filtering
4180888a09821a98ac0680fad765217302858e70fa4Paul Duffin      List<E> allEntries = new ArrayList<E>();
4190888a09821a98ac0680fad765217302858e70fa4Paul Duffin      allEntries.addAll(extremeValues);
4200888a09821a98ac0680fad765217302858e70fa4Paul Duffin      allEntries.addAll(normalValues);
4210888a09821a98ac0680fad765217302858e70fa4Paul Duffin      SortedSet<E> map = delegate.create(allEntries.toArray());
4220888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return createSubSet(map, firstExclusive, lastExclusive);
4240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4250888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    /**
4270888a09821a98ac0680fad765217302858e70fa4Paul Duffin     * Calls the smallest subSet overload that filters out the extreme values.
4280888a09821a98ac0680fad765217302858e70fa4Paul Duffin     */
4290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SortedSet<E> createSubSet(SortedSet<E> set, E firstExclusive, E lastExclusive) {
4300888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (from == Bound.NO_BOUND && to == Bound.EXCLUSIVE) {
4310888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return set.headSet(lastExclusive);
4320888a09821a98ac0680fad765217302858e70fa4Paul Duffin      } else if (from == Bound.INCLUSIVE && to == Bound.NO_BOUND) {
4330888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return set.tailSet(firstInclusive);
4340888a09821a98ac0680fad765217302858e70fa4Paul Duffin      } else if (from == Bound.INCLUSIVE && to == Bound.EXCLUSIVE) {
4350888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return set.subSet(firstInclusive, lastExclusive);
4360888a09821a98ac0680fad765217302858e70fa4Paul Duffin      } else {
4370888a09821a98ac0680fad765217302858e70fa4Paul Duffin        throw new IllegalArgumentException();
4380888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
4390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4400888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
4420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public E belowSamplesLesser() {
4430888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new UnsupportedOperationException();
4440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4450888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
4470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public E belowSamplesGreater() {
4480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new UnsupportedOperationException();
4490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4500888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
4520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public E aboveSamplesLesser() {
4530888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new UnsupportedOperationException();
4540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4550888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4560888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
4570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public E aboveSamplesGreater() {
4580888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new UnsupportedOperationException();
4590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4600888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4617dd252788645e940eada959bdde927426e2531c9Paul Duffin
4627dd252788645e940eada959bdde927426e2531c9Paul Duffin  /*
4637dd252788645e940eada959bdde927426e2531c9Paul Duffin   * TODO(cpovirk): surely we can find a less ugly solution than a class that accepts 3 parameters,
4647dd252788645e940eada959bdde927426e2531c9Paul Duffin   * exposes as many getters, does work in the constructor, and has both a superclass and a subclass
4657dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
4667dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static class SortedMapSubmapTestMapGenerator<K, V>
4677dd252788645e940eada959bdde927426e2531c9Paul Duffin      extends ForwardingTestMapGenerator<K, V> implements TestSortedMapGenerator<K, V> {
4687dd252788645e940eada959bdde927426e2531c9Paul Duffin    final Bound to;
4697dd252788645e940eada959bdde927426e2531c9Paul Duffin    final Bound from;
4707dd252788645e940eada959bdde927426e2531c9Paul Duffin    final K firstInclusive;
4717dd252788645e940eada959bdde927426e2531c9Paul Duffin    final K lastInclusive;
4727dd252788645e940eada959bdde927426e2531c9Paul Duffin    private final Comparator<Entry<K, V>> entryComparator;
4737dd252788645e940eada959bdde927426e2531c9Paul Duffin
4747dd252788645e940eada959bdde927426e2531c9Paul Duffin    public SortedMapSubmapTestMapGenerator(
4757dd252788645e940eada959bdde927426e2531c9Paul Duffin        TestSortedMapGenerator<K, V> delegate, Bound to, Bound from) {
4767dd252788645e940eada959bdde927426e2531c9Paul Duffin      super(delegate);
4777dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.to = to;
4787dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.from = from;
4797dd252788645e940eada959bdde927426e2531c9Paul Duffin
4807dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<K, V> emptyMap = delegate.create();
4817dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.entryComparator = Helpers.entryComparator(emptyMap.comparator());
4827dd252788645e940eada959bdde927426e2531c9Paul Duffin
4837dd252788645e940eada959bdde927426e2531c9Paul Duffin      // derive values for inclusive filtering from the input samples
4847dd252788645e940eada959bdde927426e2531c9Paul Duffin      SampleElements<Entry<K, V>> samples = delegate.samples();
4857dd252788645e940eada959bdde927426e2531c9Paul Duffin      @SuppressWarnings("unchecked") // no elements are inserted into the array
4867dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> samplesList = Arrays.asList(
4877dd252788645e940eada959bdde927426e2531c9Paul Duffin          samples.e0, samples.e1, samples.e2, samples.e3, samples.e4);
4887dd252788645e940eada959bdde927426e2531c9Paul Duffin      Collections.sort(samplesList, entryComparator);
4897dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.firstInclusive = samplesList.get(0).getKey();
4907dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.lastInclusive = samplesList.get(samplesList.size() - 1).getKey();
4917dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4927dd252788645e940eada959bdde927426e2531c9Paul Duffin
4937dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override public SortedMap<K, V> create(Object... entries) {
4947dd252788645e940eada959bdde927426e2531c9Paul Duffin      @SuppressWarnings("unchecked") // map generators must past entry objects
4957dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> normalValues = (List) Arrays.asList(entries);
4967dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> extremeValues = new ArrayList<Entry<K, V>>();
4977dd252788645e940eada959bdde927426e2531c9Paul Duffin
4987dd252788645e940eada959bdde927426e2531c9Paul Duffin      // prepare extreme values to be filtered out of view
4997dd252788645e940eada959bdde927426e2531c9Paul Duffin      K firstExclusive = getInnerGenerator().belowSamplesGreater().getKey();
5007dd252788645e940eada959bdde927426e2531c9Paul Duffin      K lastExclusive = getInnerGenerator().aboveSamplesLesser().getKey();
5017dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (from != Bound.NO_BOUND) {
5027dd252788645e940eada959bdde927426e2531c9Paul Duffin        extremeValues.add(getInnerGenerator().belowSamplesLesser());
5037dd252788645e940eada959bdde927426e2531c9Paul Duffin        extremeValues.add(getInnerGenerator().belowSamplesGreater());
5047dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5057dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (to != Bound.NO_BOUND) {
5067dd252788645e940eada959bdde927426e2531c9Paul Duffin        extremeValues.add(getInnerGenerator().aboveSamplesLesser());
5077dd252788645e940eada959bdde927426e2531c9Paul Duffin        extremeValues.add(getInnerGenerator().aboveSamplesGreater());
5087dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5097dd252788645e940eada959bdde927426e2531c9Paul Duffin
5107dd252788645e940eada959bdde927426e2531c9Paul Duffin      // the regular values should be visible after filtering
5117dd252788645e940eada959bdde927426e2531c9Paul Duffin      List<Entry<K, V>> allEntries = new ArrayList<Entry<K, V>>();
5127dd252788645e940eada959bdde927426e2531c9Paul Duffin      allEntries.addAll(extremeValues);
5137dd252788645e940eada959bdde927426e2531c9Paul Duffin      allEntries.addAll(normalValues);
5147dd252788645e940eada959bdde927426e2531c9Paul Duffin      SortedMap<K, V> map = (SortedMap<K, V>)
5157dd252788645e940eada959bdde927426e2531c9Paul Duffin          delegate.create((Object[])
5160888a09821a98ac0680fad765217302858e70fa4Paul Duffin              allEntries.toArray(new Entry<?, ?>[allEntries.size()]));
5177dd252788645e940eada959bdde927426e2531c9Paul Duffin
5187dd252788645e940eada959bdde927426e2531c9Paul Duffin      return createSubMap(map, firstExclusive, lastExclusive);
5197dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5207dd252788645e940eada959bdde927426e2531c9Paul Duffin
5217dd252788645e940eada959bdde927426e2531c9Paul Duffin    /**
5227dd252788645e940eada959bdde927426e2531c9Paul Duffin     * Calls the smallest subMap overload that filters out the extreme values. This method is
5237dd252788645e940eada959bdde927426e2531c9Paul Duffin     * overridden in NavigableMapTestSuiteBuilder.
5247dd252788645e940eada959bdde927426e2531c9Paul Duffin     */
5257dd252788645e940eada959bdde927426e2531c9Paul Duffin    SortedMap<K, V> createSubMap(SortedMap<K, V> map, K firstExclusive, K lastExclusive) {
5267dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (from == Bound.NO_BOUND && to == Bound.EXCLUSIVE) {
5277dd252788645e940eada959bdde927426e2531c9Paul Duffin        return map.headMap(lastExclusive);
5287dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (from == Bound.INCLUSIVE && to == Bound.NO_BOUND) {
5297dd252788645e940eada959bdde927426e2531c9Paul Duffin        return map.tailMap(firstInclusive);
5307dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (from == Bound.INCLUSIVE && to == Bound.EXCLUSIVE) {
5317dd252788645e940eada959bdde927426e2531c9Paul Duffin        return map.subMap(firstInclusive, lastExclusive);
5327dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
5337dd252788645e940eada959bdde927426e2531c9Paul Duffin        throw new IllegalArgumentException();
5347dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5357dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5367dd252788645e940eada959bdde927426e2531c9Paul Duffin
5377dd252788645e940eada959bdde927426e2531c9Paul Duffin    public final Bound getTo() {
5387dd252788645e940eada959bdde927426e2531c9Paul Duffin      return to;
5397dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5407dd252788645e940eada959bdde927426e2531c9Paul Duffin
5417dd252788645e940eada959bdde927426e2531c9Paul Duffin    public final Bound getFrom() {
5427dd252788645e940eada959bdde927426e2531c9Paul Duffin      return from;
5437dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5447dd252788645e940eada959bdde927426e2531c9Paul Duffin
5457dd252788645e940eada959bdde927426e2531c9Paul Duffin    public final TestSortedMapGenerator<K, V> getInnerGenerator() {
5467dd252788645e940eada959bdde927426e2531c9Paul Duffin      return (TestSortedMapGenerator<K, V>) delegate;
5477dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5487dd252788645e940eada959bdde927426e2531c9Paul Duffin
5497dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5507dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Entry<K, V> belowSamplesLesser() {
5517dd252788645e940eada959bdde927426e2531c9Paul Duffin      // should never reach here!
5527dd252788645e940eada959bdde927426e2531c9Paul Duffin      throw new UnsupportedOperationException();
5537dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5547dd252788645e940eada959bdde927426e2531c9Paul Duffin
5557dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5567dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Entry<K, V> belowSamplesGreater() {
5577dd252788645e940eada959bdde927426e2531c9Paul Duffin      // should never reach here!
5587dd252788645e940eada959bdde927426e2531c9Paul Duffin      throw new UnsupportedOperationException();
5597dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5607dd252788645e940eada959bdde927426e2531c9Paul Duffin
5617dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5627dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Entry<K, V> aboveSamplesLesser() {
5637dd252788645e940eada959bdde927426e2531c9Paul Duffin      // should never reach here!
5647dd252788645e940eada959bdde927426e2531c9Paul Duffin      throw new UnsupportedOperationException();
5657dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5667dd252788645e940eada959bdde927426e2531c9Paul Duffin
5677dd252788645e940eada959bdde927426e2531c9Paul Duffin    @Override
5687dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Entry<K, V> aboveSamplesGreater() {
5697dd252788645e940eada959bdde927426e2531c9Paul Duffin      // should never reach here!
5707dd252788645e940eada959bdde927426e2531c9Paul Duffin      throw new UnsupportedOperationException();
5717dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5727dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5737dd252788645e940eada959bdde927426e2531c9Paul Duffin
5747dd252788645e940eada959bdde927426e2531c9Paul Duffin  private DerivedCollectionGenerators() {}
5757dd252788645e940eada959bdde927426e2531c9Paul Duffin}
576