View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.multimap;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  import static org.junit.jupiter.api.Assumptions.assumeTrue;
26  
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.Collection;
30  import java.util.HashMap;
31  import java.util.HashSet;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Map.Entry;
36  import java.util.Set;
37  
38  import org.apache.commons.collections4.AbstractObjectTest;
39  import org.apache.commons.collections4.Bag;
40  import org.apache.commons.collections4.BulkTest;
41  import org.apache.commons.collections4.CollectionUtils;
42  import org.apache.commons.collections4.MapIterator;
43  import org.apache.commons.collections4.MultiSet;
44  import org.apache.commons.collections4.MultiValuedMap;
45  import org.apache.commons.collections4.SetValuedMap;
46  import org.apache.commons.collections4.bag.AbstractBagTest;
47  import org.apache.commons.collections4.bag.HashBag;
48  import org.apache.commons.collections4.collection.AbstractCollectionTest;
49  import org.apache.commons.collections4.map.AbstractMapTest;
50  import org.apache.commons.collections4.multiset.AbstractMultiSetTest;
51  import org.apache.commons.collections4.set.AbstractSetTest;
52  import org.apache.commons.lang3.StringUtils;
53  import org.junit.jupiter.api.Disabled;
54  import org.junit.jupiter.api.Test;
55  
56  /**
57   * Abstract test class for {@link MultiValuedMap} contract and methods.
58   * <p>
59   * To use, extend this class and implement the {@link #makeObject} method and if
60   * necessary override the {@link #makeFullMap()} method.
61   * </p>
62   */
63  public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTest {
64  
65      public class TestMultiValuedMapAsMap extends AbstractMapTest<K, Collection<V>> {
66  
67          public TestMultiValuedMapAsMap() {
68              super(StringUtils.EMPTY);
69          }
70  
71          @Override
72          public boolean areEqualElementsDistinguishable() {
73              // work-around for a problem with the EntrySet: the entries contain
74              // the wrapped collection, which will be automatically cleared
75              // when the associated key is removed from the map as the collection
76              // is not cached atm.
77              return true;
78          }
79  
80          @Override
81          protected int getIterationBehaviour() {
82              return AbstractMultiValuedMapTest.this.getIterationBehaviour();
83          }
84  
85          @Override
86          @SuppressWarnings("unchecked")
87          public Collection<V>[] getNewSampleValues() {
88              // See comment in getSampleValues() to understand why we are calling makeObject() and not
89              // getMap(). See COLLECTIONS-661 for more.
90              final boolean isSetValuedMap = AbstractMultiValuedMapTest.this.makeObject() instanceof SetValuedMap;
91              final int maxV = getSampleTotalValueCount();
92              final int maxK = getSampleKeySize();
93              final V[] sampleValues = (V[]) new Object[maxV];
94              for (int v = 0; v < maxV; v++) {
95                  // + something so that the key is different from an existing key.
96                  sampleValues[v] = makeValue(maxK + 9, v);
97              }
98              final int cpk = getSampleCountPerKey();
99              final Collection<V>[] colArr = new Collection[maxK];
100             for (int i = 0; i < maxK; i++) {
101                 List<V> coll = new ArrayList<>(cpk);
102                 for (int j = 0; j < cpk; j++) {
103                     coll.add(sampleValues[i * cpk + j]);
104                 }
105                 colArr[i] = isSetValuedMap ? new HashSet<>(coll) : coll;
106             }
107             return colArr;
108         }
109 
110         @Override
111         @SuppressWarnings("unchecked")
112         public K[] getSampleKeys() {
113             final K[] samplekeys = AbstractMultiValuedMapTest.this.getSampleKeys();
114             final int maxK = getSampleKeySize();
115             final int cpk = getSampleCountPerKey();
116             final Object[] finalKeys = new Object[maxK];
117             for (int i = 0; i < maxK; i++) {
118                 finalKeys[i] = samplekeys[i * cpk];
119             }
120             return (K[]) finalKeys;
121         }
122 
123         @Override
124         @SuppressWarnings("unchecked")
125         public Collection<V>[] getSampleValues() {
126             // Calling getMap() instead of makeObject() would make more sense, but due to concurrency
127             // issues, this may lead to intermittent issues. See COLLECTIONS-661. A better solution
128             // would be to re-design the tests, or add a boolean method to the parent.
129             final boolean isSetValuedMap = AbstractMultiValuedMapTest.this.makeObject() instanceof SetValuedMap;
130             final V[] sampleValues = AbstractMultiValuedMapTest.this.getSampleValues();
131             final int maxK = getSampleKeySize();
132             final int cpk = getSampleCountPerKey();
133             final Collection<V>[] colArr = new Collection[maxK];
134             for (int i = 0; i < maxK; i++) {
135                 final List<V> coll = new ArrayList<>(cpk);
136                 for (int j = 0; j < cpk; j++) {
137                     coll.add(sampleValues[i * cpk + j]);
138                 }
139                 colArr[i] = isSetValuedMap ? new HashSet<>(coll) : coll;
140             }
141             return colArr;
142         }
143 
144         @Override
145         public boolean isAllowNullKey() {
146             return AbstractMultiValuedMapTest.this.isAllowNullKey();
147         }
148 
149         @Override
150         public boolean isPutAddSupported() {
151             return false;
152         }
153 
154         @Override
155         public boolean isPutChangeSupported() {
156             return false;
157         }
158 
159         @Override
160         public boolean isRemoveSupported() {
161             return AbstractMultiValuedMapTest.this.isRemoveSupported();
162         }
163 
164         @Override
165         public boolean isTestSerialization() {
166             return false;
167         }
168 
169         @Override
170         public Map<K, Collection<V>> makeFullMap() {
171             return AbstractMultiValuedMapTest.this.makeFullMap().asMap();
172         }
173 
174         @Override
175         public Map<K, Collection<V>> makeObject() {
176             return AbstractMultiValuedMapTest.this.makeObject().asMap();
177         }
178     }
179 
180     public class TestMultiValuedMapEntries extends AbstractCollectionTest<Entry<K, V>> {
181         public TestMultiValuedMapEntries() {
182             super(StringUtils.EMPTY);
183         }
184 
185         @SuppressWarnings("unchecked")
186         @Override
187         public Entry<K, V>[] getFullElements() {
188             return makeFullMap().entries().toArray(new Entry[0]);
189         }
190 
191         @Override
192         protected int getIterationBehaviour() {
193             return AbstractMultiValuedMapTest.this.getIterationBehaviour();
194         }
195 
196         @Override
197         public boolean isAddSupported() {
198             // Add not supported in entries view
199             return false;
200         }
201 
202         @Override
203         public boolean isNullSupported() {
204             return AbstractMultiValuedMapTest.this.isAllowNullKey();
205         }
206 
207         @Override
208         public boolean isRemoveSupported() {
209             return AbstractMultiValuedMapTest.this.isRemoveSupported();
210         }
211 
212         @Override
213         public boolean isTestSerialization() {
214             return false;
215         }
216 
217         @Override
218         public Collection<Entry<K, V>> makeConfirmedCollection() {
219             // never gets called, reset methods are overridden
220             return null;
221         }
222 
223         @Override
224         public Collection<Entry<K, V>> makeConfirmedFullCollection() {
225             // never gets called, reset methods are overridden
226             return null;
227         }
228 
229         @Override
230         public Collection<Entry<K, V>> makeFullCollection() {
231             return AbstractMultiValuedMapTest.this.makeFullMap().entries();
232         }
233 
234         @Override
235         public Collection<Entry<K, V>> makeObject() {
236             return AbstractMultiValuedMapTest.this.makeObject().entries();
237         }
238 
239         @Override
240         public void resetEmpty() {
241             AbstractMultiValuedMapTest.this.resetEmpty();
242             setCollection(AbstractMultiValuedMapTest.this.getMap().entries());
243             TestMultiValuedMapEntries.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().entries());
244         }
245 
246         @Override
247         public void resetFull() {
248             AbstractMultiValuedMapTest.this.resetFull();
249             setCollection(AbstractMultiValuedMapTest.this.getMap().entries());
250             TestMultiValuedMapEntries.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().entries());
251         }
252 
253     }
254 
255     public class TestMultiValuedMapKeys extends AbstractMultiSetTest<K> {
256 
257         public TestMultiValuedMapKeys() {
258             super(StringUtils.EMPTY);
259         }
260 
261         @Override
262         public K[] getFullElements() {
263             return getSampleKeys();
264         }
265 
266         @Override
267         protected int getIterationBehaviour() {
268             return AbstractMultiValuedMapTest.this.getIterationBehaviour();
269         }
270 
271         @Override
272         public boolean isAddSupported() {
273             return false;
274         }
275 
276         @Override
277         public boolean isNullSupported() {
278             return AbstractMultiValuedMapTest.this.isAllowNullKey();
279         }
280 
281         @Override
282         public boolean isRemoveSupported() {
283             return false;
284         }
285 
286         @Override
287         public boolean isTestSerialization() {
288             return false;
289         }
290 
291         @Override
292         public MultiSet<K> makeFullCollection() {
293             return AbstractMultiValuedMapTest.this.makeFullMap().keys();
294         }
295 
296         @Override
297         public MultiSet<K> makeObject() {
298             return AbstractMultiValuedMapTest.this.makeObject().keys();
299         }
300 
301         @Override
302         public void resetEmpty() {
303             AbstractMultiValuedMapTest.this.resetEmpty();
304             setCollection(AbstractMultiValuedMapTest.this.getMap().keys());
305             TestMultiValuedMapKeys.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().keys());
306         }
307 
308         @Override
309         public void resetFull() {
310             AbstractMultiValuedMapTest.this.resetFull();
311             setCollection(AbstractMultiValuedMapTest.this.getMap().keys());
312             TestMultiValuedMapKeys.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().keys());
313         }
314     }
315 
316     public class TestMultiValuedMapKeySet extends AbstractSetTest<K> {
317         public TestMultiValuedMapKeySet() {
318             super(StringUtils.EMPTY);
319         }
320 
321         @SuppressWarnings("unchecked")
322         @Override
323         public K[] getFullElements() {
324             return (K[]) AbstractMultiValuedMapTest.this.makeFullMap().keySet().toArray();
325         }
326 
327         @Override
328         protected int getIterationBehaviour() {
329             return AbstractMultiValuedMapTest.this.getIterationBehaviour();
330         }
331 
332         @Override
333         public boolean isAddSupported() {
334             return false;
335         }
336 
337         @Override
338         public boolean isNullSupported() {
339             return AbstractMultiValuedMapTest.this.isAllowNullKey();
340         }
341 
342         @Override
343         public boolean isRemoveSupported() {
344             return AbstractMultiValuedMapTest.this.isRemoveSupported();
345         }
346 
347         @Override
348         public boolean isTestSerialization() {
349             return false;
350         }
351 
352         @Override
353         public Set<K> makeFullCollection() {
354             return AbstractMultiValuedMapTest.this.makeFullMap().keySet();
355         }
356 
357         @Override
358         public Set<K> makeObject() {
359             return AbstractMultiValuedMapTest.this.makeObject().keySet();
360         }
361     }
362 
363     public class TestMultiValuedMapValues extends AbstractCollectionTest<V> {
364         public TestMultiValuedMapValues() {
365             super(StringUtils.EMPTY);
366         }
367 
368         @Override
369         public V[] getFullElements() {
370             return getSampleValues();
371         }
372 
373         @Override
374         protected int getIterationBehaviour() {
375             return AbstractMultiValuedMapTest.this.getIterationBehaviour();
376         }
377 
378         @Override
379         public boolean isAddSupported() {
380             return false;
381         }
382 
383         @Override
384         public boolean isNullSupported() {
385             return AbstractMultiValuedMapTest.this.isAllowNullKey();
386         }
387 
388         @Override
389         public boolean isRemoveSupported() {
390             return AbstractMultiValuedMapTest.this.isRemoveSupported();
391         }
392 
393         @Override
394         public boolean isTestSerialization() {
395             return false;
396         }
397 
398         @Override
399         public Collection<V> makeConfirmedCollection() {
400             // never gets called, reset methods are overridden
401             return null;
402         }
403 
404         @Override
405         public Collection<V> makeConfirmedFullCollection() {
406             // never gets called, reset methods are overridden
407             return null;
408         }
409 
410         @Override
411         public Collection<V> makeFullCollection() {
412             return AbstractMultiValuedMapTest.this.makeFullMap().values();
413         }
414 
415         @Override
416         public Collection<V> makeObject() {
417             return AbstractMultiValuedMapTest.this.makeObject().values();
418         }
419 
420         @Override
421         public void resetEmpty() {
422             AbstractMultiValuedMapTest.this.resetEmpty();
423             setCollection(AbstractMultiValuedMapTest.this.getMap().values());
424             TestMultiValuedMapValues.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().values());
425         }
426 
427         @Override
428         public void resetFull() {
429             AbstractMultiValuedMapTest.this.resetFull();
430             setCollection(AbstractMultiValuedMapTest.this.getMap().values());
431             TestMultiValuedMapValues.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().values());
432         }
433     }
434 
435     /** Map created by reset(). */
436     protected MultiValuedMap<K, V> map;
437 
438     /** MultiValuedHashMap created by reset(). */
439     protected MultiValuedMap<K, V> confirmed;
440 
441     public AbstractMultiValuedMapTest(final String testName) {
442         super(testName);
443     }
444 
445     protected void addSampleMappings(final MultiValuedMap<? super K, ? super V> map) {
446         final K[] keys = getSampleKeys();
447         final V[] values = getSampleValues();
448         for (int i = 0; i < keys.length; i++) {
449             map.put(keys[i], values[i]);
450         }
451     }
452 
453     public BulkTest bulkTestAsMap() {
454         return new TestMultiValuedMapAsMap();
455     }
456 
457     // Bulk Tests
458     /**
459      * Bulk test {@link MultiValuedMap#entries()}. This method runs through all
460      * of the tests in {@link AbstractCollectionTest}. After modification
461      * operations, {@link #verify()} is invoked to ensure that the map and the
462      * other collection views are still valid.
463      *
464      * @return a {@link AbstractCollectionTest} instance for testing the map's
465      *         values collection
466      */
467     public BulkTest bulkTestMultiValuedMapEntries() {
468         return new TestMultiValuedMapEntries();
469     }
470 
471     /**
472      * Bulk test {@link MultiValuedMap#keys()}. This method runs through all of
473      * the tests in {@link AbstractBagTest}. After modification operations,
474      * {@link #verify()} is invoked to ensure that the map and the other
475      * collection views are still valid.
476      *
477      * @return a {@link AbstractBagTest} instance for testing the map's values
478      *         collection
479      */
480     public BulkTest bulkTestMultiValuedMapKeys() {
481         return new TestMultiValuedMapKeys();
482     }
483 
484     /**
485      * Bulk test {@link MultiValuedMap#keySet()}. This method runs through all
486      * of the tests in {@link AbstractSetTest}. After modification operations,
487      * {@link #verify()} is invoked to ensure that the map and the other
488      * collection views are still valid.
489      *
490      * @return a {@link AbstractSetTest} instance for testing the map's key set
491      */
492     public BulkTest bulkTestMultiValuedMapKeySet() {
493         return new TestMultiValuedMapKeySet();
494     }
495 
496     /**
497      * Bulk test {@link MultiValuedMap#values()}. This method runs through all
498      * of the tests in {@link AbstractCollectionTest}. After modification
499      * operations, {@link #verify()} is invoked to ensure that the map and the
500      * other collection views are still valid.
501      *
502      * @return a {@link AbstractCollectionTest} instance for testing the map's
503      *         values collection
504      */
505     public BulkTest bulkTestMultiValuedMapValues() {
506         return new TestMultiValuedMapValues();
507     }
508 
509     @Override
510     public String getCompatibilityVersion() {
511         return "4.1"; // MultiValuedMap has been added in version 4.1
512     }
513 
514     public MultiValuedMap<K, V> getConfirmed() {
515         return confirmed;
516     }
517 
518     /**
519      * Gets a flag specifying the iteration behavior of the map.
520      * This is used to change the assertions used by specific tests.
521      * The default implementation returns 0 which indicates ordered iteration behavior.
522      *
523      * @return the iteration behavior
524      * @see AbstractCollectionTest#UNORDERED
525      */
526     protected int getIterationBehaviour() {
527         return 0;
528     }
529 
530     public MultiValuedMap<K, V> getMap() {
531         return map;
532     }
533 
534     public int getSampleCountPerKey() {
535         return 8;
536     }
537 
538     /**
539      * Returns the set of keys in the mappings used to test the map. This method
540      * must return an array with the same length as {@link #getSampleValues()}
541      * and all array elements must be different. The default implementation
542      * constructs a set of String keys, and includes a single null key if
543      * {@link #isAllowNullKey()} returns {@code true}.
544      */
545     @SuppressWarnings("unchecked")
546     public K[] getSampleKeys() {
547         final Object[] result = new Object[getSampleTotalValueCount()];
548         final int cpk = getSampleCountPerKey();
549         int k = 0;
550         for (int i = 0; i < result.length; i += cpk, k++) {
551             final K key = makeKey(k);
552             for (int j = 0; j < cpk; j++) {
553                 result[i + j] = key;
554             }
555         }
556         return (K[]) result;
557     }
558 
559     public int getSampleKeySize() {
560         return 256;
561     }
562 
563     public int getSampleTotalValueCount() {
564         return getSampleCountPerKey() * getSampleKeySize();
565     }
566 
567     /**
568      * Returns the set of values in the mappings used to test the map. This
569      * method must return an array with the same length as
570      * {@link #getSampleKeys()}. The default implementation constructs a set of
571      * String values
572      */
573     @SuppressWarnings("unchecked")
574     public V[] getSampleValues() {
575         final Object[] result = new Object[getSampleTotalValueCount()];
576         final int cpk = getSampleCountPerKey();
577         int k = 0;
578         for (int i = 0; i < result.length; i += cpk, k++) {
579             for (int j = 0; j < cpk; j++) {
580                 result[i + j] = makeValue(k, j);
581             }
582         }
583         return (V[]) result;
584     }
585 
586     /**
587      * Returns true if the maps produced by {@link #makeObject()} and
588      * {@link #makeFullMap()} support the {@code put} and
589      * {@code putAll} operations adding new mappings.
590      * <p>
591      * Default implementation returns true. Override if your collection class
592      * does not support put adding.
593      * </p>
594      */
595     public boolean isAddSupported() {
596         return true;
597     }
598 
599     /**
600      * Returns true if the maps produced by {@link #makeObject()} and
601      * {@link #makeFullMap()} supports null keys.
602      * <p>
603      * Default implementation returns true. Override if your collection class
604      * does not support null keys.
605      * </p>
606      */
607     public boolean isAllowNullKey() {
608         return true;
609     }
610 
611     /**
612      * Returns true if the maps produced by {@link #makeObject()} and
613      * {@link #makeFullMap()} supports set value.
614      * <p>
615      * Default implementation returns false. Override if your collection class
616      * supports set value.
617      * </p>
618      */
619     public boolean isHashSetValue() {
620         return false;
621     }
622 
623     /**
624      * Returns true if the maps produced by {@link #makeObject()} and
625      * {@link #makeFullMap()} support the {@code remove} and
626      * {@code clear} operations.
627      * <p>
628      * Default implementation returns true. Override if your collection class
629      * does not support removal operations.
630      * </p>
631      */
632     public boolean isRemoveSupported() {
633         return true;
634     }
635 
636     @Override
637     public boolean isTestSerialization() {
638         return true;
639     }
640 
641     /**
642      * Override to return a MultiValuedMap other than ArrayListValuedHashMap
643      * as the confirmed map.
644      *
645      * @return a MultiValuedMap that is known to be valid
646      */
647     public MultiValuedMap<K, V> makeConfirmedMap() {
648         return new ArrayListValuedHashMap<>();
649     }
650 
651     protected MultiValuedMap<K, V> makeFullMap() {
652         final MultiValuedMap<K, V> map = makeObject();
653         addSampleMappings(map);
654         return map;
655     }
656 
657     <E> E makeKey(final int key) {
658         return (E) new StringBuilder("k").append(key).toString();
659     }
660 
661     @Override
662     public abstract MultiValuedMap<K, V> makeObject();
663 
664     <E> E makeValue(final int key, final int value) {
665         return (E) new StringBuilder("v").append(key).append('_').append(value).toString();
666     }
667 
668     /**
669      * Resets the {@link #map} and {@link #confirmed} fields to empty.
670      */
671     public void resetEmpty() {
672         this.map = makeObject();
673         this.confirmed = makeConfirmedMap();
674     }
675 
676     /**
677      * Resets the {@link #map} and {@link #confirmed} fields to full.
678      */
679     public void resetFull() {
680         this.map = makeFullMap();
681         this.confirmed = makeConfirmedMap();
682         final K[] k = getSampleKeys();
683         final V[] v = getSampleValues();
684         for (int i = 0; i < k.length; i++) {
685             confirmed.put(k[i], v[i]);
686         }
687     }
688 
689 //    public void testKeyedIterator() {
690 //        final MultiValuedMap<K, V> map = makeFullMap();
691 //        final ArrayList<Object> actual = new ArrayList<Object>(IteratorUtils.toList(map.iterator("k0")));
692 //        final ArrayList<Object> expected = new ArrayList<Object>(Arrays.asList("v1_1", "v0_1"));
693 //        assertEquals(expected, actual);
694 //    }
695 
696     public void setConfirmed(final MultiValuedMap<K, V> map) {
697         this.confirmed = map;
698     }
699 
700     @Test
701     @SuppressWarnings("unchecked")
702     public void testAddMappingThroughGet() {
703         assumeTrue(isAddSupported());
704         resetEmpty();
705         final MultiValuedMap<K, V> map = getMap();
706         final Collection<V> col1 = map.get((K) "k0");
707         final Collection<V> col2 = map.get((K) "k0");
708         assertTrue(col1.isEmpty());
709         assertTrue(col2.isEmpty());
710         assertEquals(0, map.size());
711         col1.add((V) "v1_1");
712         col2.add((V) "v0_1");
713         assertTrue(map.containsKey("k0"));
714         assertTrue(map.containsMapping("k0", "v1_1"));
715         assertTrue(map.containsMapping("k0", "v0_1"));
716         assertTrue(map.containsValue("v1_1"));
717         assertTrue(map.containsValue("v0_1"));
718         assertTrue(col1.contains("v0_1"));
719         assertTrue(col2.contains("v1_1"));
720     }
721 
722     /*public void testRemoveViaGetCollectionRemove() {
723         if (!isRemoveSupported()) {
724             return;
725         }
726         final MultiValuedMap<K, V> map = makeFullMap();
727         Collection<V> values = map.get("k0");
728         values.remove("v1_1");
729         values.remove("v0_1");
730         assertFalse(map.containsKey("k0"));
731         assertEquals(4, map.size());
732     }*/
733 
734 //    public void testRemoveAllViaKeyedIterator() {
735 //        if (!isRemoveSupported()) {
736 //            return;
737 //        }
738 //        final MultiValuedMap<K, V> map = makeFullMap();
739 //        for (final Iterator<?> i = map.iterator("k0"); i.hasNext();) {
740 //            i.next();
741 //            i.remove();
742 //        }
743 //        assertNull(map.get("k0"));
744 //        assertEquals(4, map.size());
745 //    }
746 
747     @Test
748     public void testAsMapGet_Empty() {
749         resetEmpty();
750         final Map<K, Collection<V>> mapCol = getMap().asMap();
751         assertNull(mapCol.get("k0"));
752         assertEquals(0, mapCol.size());
753     }
754 
755     @Test
756     public void testAsMapGet_Full() {
757         resetFull();
758         final Map<K, Collection<V>> mapCol = getMap().asMap();
759         final int maxK = getSampleKeySize();
760         final int maxV = getSampleCountPerKey();
761         for (int k = 0; k < maxK; k++) {
762             final Collection<V> col = mapCol.get(makeKey(k));
763             for (int v = 0; v < maxV; v++) {
764                 assertTrue(col.contains(makeValue(k, v)));
765             }
766         }
767     }
768 
769     @Test
770     public void testAsMapRemove() {
771         assumeTrue(isRemoveSupported());
772         resetFull();
773         final Map<K, Collection<V>> mapCol = getMap().asMap();
774         final int maxK = getSampleKeySize();
775         int expectedSize = getMap().size();
776         for (int k = 0; k < maxK; k++) {
777             final K key = makeKey(k);
778             mapCol.remove(key);
779             assertFalse(getMap().containsKey(key));
780             expectedSize -= getSampleCountPerKey();
781             assertEquals(expectedSize, getMap().size());
782         }
783         assertFalse(getMap().containsKey("k0"));
784         assertEquals(0, getMap().size());
785     }
786 
787     @Test
788     public void testContainsValue() {
789         final MultiValuedMap<K, V> map = makeFullMap();
790         final int maxK = getSampleKeySize();
791         final int maxV = getSampleCountPerKey();
792         for (int k = 0; k < maxK; k++) {
793             for (int v = 0; v < maxV; v++) {
794                 assertTrue(map.containsValue(makeValue(k, v)));
795             }
796         }
797         assertFalse(map.containsValue("quatro"));
798     }
799 
800     @Test
801     @SuppressWarnings("unchecked")
802     public void testContainsValue_Key() {
803         final MultiValuedMap<K, V> map = makeFullMap();
804         final int maxK = getSampleKeySize();
805         final int maxV = getSampleCountPerKey();
806         for (int k = 0; k < maxK; k++) {
807             for (int v = 0; v < maxV; v++) {
808                 assertTrue(map.containsMapping(makeKey(k), makeValue(k, v)));            }
809         }
810         assertFalse(map.containsMapping("k1", "2"));
811         if (!isAddSupported()) {
812             return;
813         }
814         map.put((K) "A", (V) "AA");
815         assertTrue(map.containsMapping("A", "AA"));
816         assertFalse(map.containsMapping("A", "AB"));
817     }
818 
819     /**
820      * Manual serialization testing as this class cannot easily extend the AbstractTestMap
821      */
822     @Test
823     public void testEmptyMapCompatibility() throws Exception {
824         final MultiValuedMap<?, ?> map = makeObject();
825         final MultiValuedMap<?, ?> map2 =
826                 (MultiValuedMap<?, ?>) readExternalFormFromDisk(getCanonicalEmptyCollectionName(map));
827         assertEquals(0, map2.size(), "Map is empty");
828     }
829 
830     @Test
831     public void testEntriesCollectionIterator() {
832         final MultiValuedMap<K, V> map = makeFullMap();
833         final Collection<V> values = new ArrayList<>(map.values());
834         for (final Entry<K, V> entry : map.entries()) {
835             assertTrue(map.containsMapping(entry.getKey(), entry.getValue()));
836             assertTrue(values.contains(entry.getValue()));
837             if (isRemoveSupported()) {
838                 assertTrue(values.remove(entry.getValue()));
839             }
840         }
841         if (isRemoveSupported()) {
842             assertTrue(values.isEmpty());
843         }
844     }
845 
846     @SuppressWarnings({ "rawtypes", "unchecked" })
847     @Test
848     @Disabled("There is no code to create this test fixture?")
849     public void testFullMapCompatibility() throws Exception {
850         final MultiValuedMap map = makeFullMap();
851         final MultiValuedMap map2 =
852                 (MultiValuedMap) readExternalFormFromDisk(getCanonicalFullCollectionName(map));
853         assertEquals(map.size(), map2.size(), "Map is the right size");
854         for (final Object key : map.keySet()) {
855             assertTrue(CollectionUtils.isEqualCollection(map.get(key), map2.get(key)),
856                     "Map had inequal elements");
857             if (isRemoveSupported()) {
858                 map2.remove(key);
859             }
860         }
861         if (isRemoveSupported()) {
862             assertEquals(0, map2.size(), "Map had extra values");
863         }
864     }
865 
866 //    @SuppressWarnings("unchecked")
867 //    public void testIterator_Key() {
868 //        final MultiValuedMap<K, V> map = makeFullMap();
869 //        Iterator<V> it = map.iterator("k0");
870 //        assertTrue( it.hasNext());
871 //        Set<V> values = new HashSet<V>();
872 //        while (it.hasNext()) {
873 //            values.add(it.next());
874 //        }
875 //        assertTrue( values.contains("v0_1"));
876 //        assertTrue( values.contains("v1_1"));
877 //        assertFalse(map.iterator("A").hasNext());
878 //        assertFalse(map.iterator("A").hasNext());
879 //        if (!isAddSupported()) {
880 //            return;
881 //        }
882 //        map.put((K) "A", (V) "AA");
883 //        it = map.iterator("A");
884 //        assertTrue( it.hasNext());
885 //        it.next();
886 //        assertFalse(it.hasNext());
887 //    }
888 
889     @Test
890     @SuppressWarnings("unchecked")
891     public void testGet() {
892         final MultiValuedMap<K, V> map = makeFullMap();
893         final int maxK = getSampleKeySize();
894         final int maxV = getSampleCountPerKey();
895         for (int k = 0; k < maxK; k++) {
896             for (int v = 0; v < maxV; v++) {
897                 assertTrue(map.get((K) makeKey(k)).contains(makeValue(k, v)));
898             }
899         }
900     }
901 
902     @Test
903     public void testKeyContainsValue() {
904         final MultiValuedMap<K, V> map = makeFullMap();
905         final int maxK = getSampleKeySize();
906         final int maxV = getSampleCountPerKey();
907         for (int k = 0; k < maxK; k++) {
908             for (int v = 0; v < maxV; v++) {
909                 assertTrue(map.containsMapping(makeKey(k), makeValue(k, v)));
910             }
911         }
912         assertFalse(map.containsMapping("k", "v"));
913     }
914 
915     @Test
916     @SuppressWarnings({ "unchecked", "cast" })
917     public void testKeysBagContainsAll() {
918         final MultiValuedMap<K, V> map = makeFullMap();
919         final MultiSet<K> keyMultiSet = map.keys();
920 
921         final List<String> col = new ArrayList<>();
922         final int maxK = getSampleKeySize();
923         for (int k = 0; k < maxK; k++) {
924             col.add(makeKey(k));
925         }
926         for (int k = 0; k < maxK; k++) {
927             col.add(makeKey(k));
928         }
929         // Make sure we test Collection API
930         assertTrue(keyMultiSet.containsAll((Collection<K>) col));
931     }
932 
933     @Test
934     public void testKeysBagIterator() {
935         final MultiValuedMap<K, V> map = makeFullMap();
936         final Collection<K> col = new ArrayList<>();
937         for (K element : map.keys()) {
938             col.add(element);
939         }
940         final Bag<K> bag = new HashBag<>(col);
941         final int maxK = getSampleKeySize();
942         for (int k = 0; k < maxK; k++) {
943             assertEquals(getSampleCountPerKey(), bag.getCount(makeKey(k)));
944         }
945         assertEquals(getSampleTotalValueCount(), bag.size());
946     }
947 
948     @Test
949     public void testKeySetSize() {
950         final MultiValuedMap<K, V> map = makeFullMap();
951         assertEquals(getSampleKeySize(), map.keySet().size());
952     }
953 
954     @Test
955     public void testKeysMultiSet() {
956         final MultiValuedMap<K, V> map = makeFullMap();
957         final MultiSet<K> keyMultiSet = map.keys();
958         final int maxK = getSampleKeySize();
959         for (int k = 0; k < maxK; k++) {
960             assertEquals(getSampleCountPerKey(), keyMultiSet.getCount(makeKey(k)));
961         }
962         assertEquals(0, keyMultiSet.getCount("conut"));
963         assertEquals(getSampleTotalValueCount(), keyMultiSet.size());
964     }
965 
966     @Test
967     @SuppressWarnings("unchecked")
968     public void testMapEquals() {
969         assumeTrue(isAddSupported());
970         final MultiValuedMap<K, V> one = makeObject();
971         final Integer value = Integer.valueOf(1);
972         one.put((K) "One", (V) value);
973         one.removeMapping("One", value);
974 
975         final MultiValuedMap<K, V> two = makeObject();
976         assertEquals(two, one);
977     }
978 
979     @Test
980     public void testMapIterator() {
981         resetEmpty();
982         MapIterator<K, V> mapIt  = getMap().mapIterator();
983         assertFalse(mapIt.hasNext());
984 
985         resetFull();
986         mapIt = getMap().mapIterator();
987         while (mapIt.hasNext()) {
988             final K key = mapIt.next();
989             final V value = mapIt.getValue();
990             assertTrue(getMap().containsMapping(key, value));
991         }
992     }
993 
994     @Test
995     public void testMapIteratorRemove() {
996         assumeTrue(isRemoveSupported());
997         resetFull();
998         final MapIterator<K, V> mapIt = getMap().mapIterator();
999         while (mapIt.hasNext()) {
1000             mapIt.next();
1001             mapIt.remove();
1002         }
1003         assertTrue(getMap().isEmpty());
1004     }
1005 
1006     @Test
1007     @SuppressWarnings("unchecked")
1008     public void testMapIteratorUnsupportedSet() {
1009         resetFull();
1010         final MapIterator<K, V> mapIt = getMap().mapIterator();
1011         mapIt.next();
1012         assertThrows(UnsupportedOperationException.class, () -> mapIt.setValue((V) "some value"));
1013     }
1014 
1015     @Test
1016     public void testMultipleValues() {
1017         final MultiValuedMap<K, V> map = makeFullMap();
1018         final int maxK = getSampleKeySize();
1019         final int maxV = getSampleCountPerKey();
1020         for (int k = 0; k < maxK; k++) {
1021             final Collection<V> col = map.get(makeKey(k));
1022             for (int v = 0; v < maxV; v++) {
1023                 assertTrue(col.contains(makeValue(k, v)));
1024             }
1025         }
1026 
1027     }
1028 
1029     @Test
1030     public void testMultiValuedMapIterator() {
1031         final MultiValuedMap<K, V> map = makeFullMap();
1032         final MapIterator<K, V> it = map.mapIterator();
1033         assertThrows(IllegalStateException.class, () -> it.getKey());
1034         assertThrows(IllegalStateException.class, () -> it.getValue());
1035         if (isAddSupported()) {
1036             assertThrows(IllegalStateException.class, () -> it.setValue((V) "V"));
1037         }
1038         if (!isHashSetValue() && isAddSupported()) {
1039             assertTrue(it.hasNext());
1040             final MultiValuedMap<K, V> dejaVu = makeObject();
1041             while (it.hasNext()) {
1042                 final K next = it.next();
1043                 assertNotNull(next);
1044                 final K itKey = it.getKey();
1045                 assertEquals(next, itKey);
1046                 final V itValue = it.getValue();
1047                 dejaVu.put(itKey, itValue);
1048                 assertThrows(UnsupportedOperationException.class, () -> it.setValue((V) "threetrois"));
1049             }
1050             assertEquals(map, dejaVu);
1051             assertEquals(dejaVu, map);
1052             assertThrows(UnsupportedOperationException.class, () -> it.setValue((V) "threetrois"));
1053         }
1054     }
1055 
1056     @Test
1057     @SuppressWarnings("unchecked")
1058     public void testNoMappingReturnsEmptyCol() {
1059         final MultiValuedMap<K, V> map = makeFullMap();
1060         assertTrue(map.get((K) "whatever").isEmpty());
1061     }
1062 
1063     @Test
1064     @SuppressWarnings("unchecked")
1065     public void testPutAll_KeyIterable() {
1066         assumeTrue(isAddSupported());
1067         final MultiValuedMap<K, V> map = makeObject();
1068         Collection<V> coll = (Collection<V>) Arrays.asList("X", "Y", "Z");
1069 
1070         assertTrue(map.putAll((K) "A", coll));
1071         assertEquals(3, map.get((K) "A").size());
1072         assertTrue(map.containsMapping("A", "X"));
1073         assertTrue(map.containsMapping("A", "Y"));
1074         assertTrue(map.containsMapping("A", "Z"));
1075 
1076         assertThrows(NullPointerException.class, () -> map.putAll((K) "A", null),
1077                 "expecting NullPointerException");
1078 
1079         assertEquals(3, map.get((K) "A").size());
1080         assertTrue(map.containsMapping("A", "X"));
1081         assertTrue(map.containsMapping("A", "Y"));
1082         assertTrue(map.containsMapping("A", "Z"));
1083 
1084         assertFalse(map.putAll((K) "A", new ArrayList<>()));
1085         assertEquals(3, map.get((K) "A").size());
1086         assertTrue(map.containsMapping("A", "X"));
1087         assertTrue(map.containsMapping("A", "Y"));
1088         assertTrue(map.containsMapping("A", "Z"));
1089 
1090         coll = (Collection<V>) Arrays.asList("M");
1091         assertTrue(map.putAll((K) "A", coll));
1092         assertEquals(4, map.get((K) "A").size());
1093         assertTrue(map.containsMapping("A", "X"));
1094         assertTrue(map.containsMapping("A", "Y"));
1095         assertTrue(map.containsMapping("A", "Z"));
1096         assertTrue(map.containsMapping("A", "M"));
1097     }
1098 
1099     @Test
1100     @SuppressWarnings("unchecked")
1101     public void testPutAll_Map1() {
1102         assumeTrue(isAddSupported());
1103         final MultiValuedMap<K, V> original = makeObject();
1104         original.put((K) "key", (V) "object1");
1105         original.put((K) "key", (V) "object2");
1106 
1107         final MultiValuedMap<K, V> test = makeObject();
1108         test.put((K) "keyA", (V) "objectA");
1109         test.put((K) "key", (V) "object0");
1110         test.putAll(original);
1111 
1112         final MultiValuedMap<K, V> originalNull = null;
1113         assertThrows(NullPointerException.class, () -> test.putAll(originalNull),
1114                 "expecting NullPointerException");
1115 
1116         assertEquals(2, test.keySet().size());
1117         assertEquals(4, test.size());
1118         assertEquals(1, test.get((K) "keyA").size());
1119         assertEquals(3, test.get((K) "key").size());
1120         assertTrue(test.containsValue("objectA"));
1121         assertTrue(test.containsValue("object0"));
1122         assertTrue(test.containsValue("object1"));
1123         assertTrue(test.containsValue("object2"));
1124     }
1125 
1126     @Test
1127     @SuppressWarnings("unchecked")
1128     public void testPutAll_Map2() {
1129         assumeTrue(isAddSupported());
1130         final Map<K, V> original = new HashMap<>();
1131         original.put((K) "keyX", (V) "object1");
1132         original.put((K) "keyY", (V) "object2");
1133 
1134         final MultiValuedMap<K, V> test = makeObject();
1135         test.put((K) "keyA", (V) "objectA");
1136         test.put((K) "keyX", (V) "object0");
1137         test.putAll(original);
1138 
1139         final Map<K, V> originalNull = null;
1140         assertThrows(NullPointerException.class, () -> test.putAll(originalNull),
1141                 "expecting NullPointerException");
1142 
1143         assertEquals(3, test.keySet().size());
1144         assertEquals(4, test.size());
1145         assertEquals(1, test.get((K) "keyA").size());
1146         assertEquals(2, test.get((K) "keyX").size());
1147         assertEquals(1, test.get((K) "keyY").size());
1148         assertTrue(test.containsValue("objectA"));
1149         assertTrue(test.containsValue("object0"));
1150         assertTrue(test.containsValue("object1"));
1151         assertTrue(test.containsValue("object2"));
1152     }
1153 
1154     @Test
1155     @SuppressWarnings("unchecked")
1156     public void testRemove_KeyItem() {
1157         assumeTrue(isAddSupported());
1158         assumeTrue(isRemoveSupported());
1159         final MultiValuedMap<K, V> map = makeObject();
1160         map.put((K) "A", (V) "AA");
1161         map.put((K) "A", (V) "AB");
1162         map.put((K) "A", (V) "AC");
1163         assertFalse(map.removeMapping("C", "CA"));
1164         assertFalse(map.removeMapping("A", "AD"));
1165         assertTrue(map.removeMapping("A", "AC"));
1166         assertTrue(map.removeMapping("A", "AB"));
1167         assertTrue(map.removeMapping("A", "AA"));
1168         //assertEquals(new MultiValuedHashMap<K, V>(), map);
1169     }
1170 
1171     @Test
1172     @SuppressWarnings("unchecked")
1173     public void testRemoveAllViaEntriesIterator() {
1174         assumeTrue(isRemoveSupported());
1175         final MultiValuedMap<K, V> map = makeFullMap();
1176         for (final Iterator<?> i = map.entries().iterator(); i.hasNext();) {
1177             i.next();
1178             i.remove();
1179         }
1180         assertTrue(map.get((K) "k0").isEmpty());
1181         assertEquals(0, map.size());
1182     }
1183 
1184     @Test
1185     @SuppressWarnings("unchecked")
1186     public void testRemoveAllViaValuesIterator() {
1187         assumeTrue(isRemoveSupported());
1188         final MultiValuedMap<K, V> map = makeFullMap();
1189         for (final Iterator<?> i = map.values().iterator(); i.hasNext();) {
1190             i.next();
1191             i.remove();
1192         }
1193         assertTrue(map.get((K) "k0").isEmpty());
1194         assertTrue(map.isEmpty());
1195     }
1196 
1197     @Test
1198     public void testRemoveMappingThroughGet() {
1199         assumeTrue(isRemoveSupported());
1200         resetFull();
1201         final MultiValuedMap<K, V> map = getMap();
1202         final int cpk = getSampleCountPerKey();
1203         int expectedCount = getSampleTotalValueCount();
1204         assertEquals(expectedCount, map.size());
1205         for (int k = 0; k < getSampleKeySize(); k++) {
1206             final Object key = makeKey(k);
1207             @SuppressWarnings("unchecked")
1208             Collection<V> col = map.get((K) key);
1209             assertEquals(cpk, col.size());
1210             for (int i = 0; i < cpk; i++) {
1211                 final Object value = makeValue(k, i);
1212                 assertTrue(col.remove(value), () -> value.toString());
1213             }
1214             for (int i = 0; i < cpk; i++) {
1215                 assertFalse(col.remove(makeValue(k, i)));
1216             }
1217             assertFalse(map.containsKey(key));
1218             for (int i = 0; i < cpk; i++) {
1219                 assertFalse(map.containsMapping(key, i));
1220             }
1221             for (int i = 0; i < cpk; i++) {
1222                 assertFalse(map.containsValue(makeValue(k, i)));
1223             }
1224             expectedCount -= cpk;
1225             assertEquals(expectedCount, map.size());
1226             col = map.remove(key);
1227             assertNotNull(col);
1228             assertEquals(0, col.size());
1229         }
1230     }
1231 
1232     @Test
1233     public void testRemoveMappingThroughGetIterator() {
1234         assumeTrue(isRemoveSupported());
1235         resetFull();
1236         final MultiValuedMap<K, V> map = getMap();
1237         int expectedSize = map.size();
1238         final int maxK = getSampleKeySize();
1239         for (int k = 0; k < maxK; k++) {
1240             final String key = makeKey(k);
1241             final int cpk = getSampleCountPerKey();
1242             @SuppressWarnings("unchecked")
1243             final Iterator<V> it = map.get((K) key).iterator();
1244             while (it.hasNext()) {
1245                 it.next();
1246                 it.remove();
1247             }
1248             assertFalse(map.containsKey(key));
1249             for (int j = 0; j < cpk; j++) {
1250                 assertFalse(map.containsMapping(key, makeValue(k + 1, j)));
1251                 final Object value = makeValue(k, j);
1252                 assertFalse(map.containsMapping(key, value));
1253                 assertFalse(map.containsValue(value));
1254             }
1255             expectedSize -= cpk;
1256             assertEquals(expectedSize, map.size());
1257             final Collection<V> coll = map.remove("k0");
1258             assertNotNull(coll);
1259             assertEquals(0, coll.size());
1260         }
1261     }
1262 
1263     @Test
1264     public void testRemoveViaValuesRemove() {
1265         assumeTrue(isRemoveSupported());
1266         final MultiValuedMap<K, V> map = makeFullMap();
1267         final Collection<V> values = map.values();
1268         final int maxK = getSampleKeySize();
1269         final int maxV = getSampleCountPerKey();
1270         int expectedSize = map.size();
1271         for (int k = 0; k < maxK; k++) {
1272             for (int v = 0; v < maxV; v++) {
1273                 values.remove(makeValue(k, v));
1274             }
1275             assertFalse(map.containsKey(makeKey(k)));
1276             expectedSize -= maxV;
1277             assertEquals(expectedSize, map.size());
1278         }
1279         assertEquals(0, map.size());
1280     }
1281 
1282     @Test
1283     public void testSize() {
1284         assertEquals(getSampleTotalValueCount(), makeFullMap().size());
1285     }
1286 
1287     @Test
1288     @SuppressWarnings("unchecked")
1289     public void testSize_Key() {
1290         final MultiValuedMap<K, V> map = makeFullMap();
1291         final int maxK = getSampleKeySize();
1292         for (int k = 0; k < maxK; k++) {
1293             assertEquals(getSampleCountPerKey(), map.get((K) makeKey(k)).size());
1294         }
1295         if (!isAddSupported()) {
1296             return;
1297         }
1298         map.put((K) "A", (V) "AA");
1299         assertEquals(1, map.get((K) "A").size());
1300         // assertEquals(0, map.get("B").size());
1301         map.put((K) "B", (V) "BA");
1302         assertEquals(1, map.get((K) "A").size());
1303         assertEquals(1, map.get((K) "B").size());
1304         map.put((K) "B", (V) "BB");
1305         assertEquals(1, map.get((K) "A").size());
1306         assertEquals(2, map.get((K) "B").size());
1307         map.put((K) "B", (V) "BC");
1308         assertEquals(1, map.get((K) "A").size());
1309         assertEquals(3, map.get((K) "B").size());
1310         if (!isRemoveSupported()) {
1311             return;
1312         }
1313         map.remove("A");
1314         // assertEquals(0, map.get("A").size());
1315         assertEquals(3, map.get((K) "B").size());
1316         map.removeMapping("B", "BC");
1317         // assertEquals(0, map.get("A").size());
1318         assertEquals(2, map.get((K) "B").size());
1319     }
1320 
1321     @Test
1322     @SuppressWarnings("unchecked")
1323     public void testSizeWithPutRemove() {
1324         assumeTrue(isAddSupported());
1325         assumeTrue(isRemoveSupported());
1326         final MultiValuedMap<K, V> map = makeObject();
1327         assertEquals(0, map.size());
1328         map.put((K) "A", (V) "AA");
1329         assertEquals(1, map.size());
1330         map.put((K) "B", (V) "BA");
1331         assertEquals(2, map.size());
1332         map.put((K) "B", (V) "BB");
1333         assertEquals(3, map.size());
1334         map.put((K) "B", (V) "BC");
1335         assertEquals(4, map.size());
1336         map.remove("A");
1337         assertEquals(3, map.size());
1338         map.removeMapping("B", "BC");
1339         assertEquals(2, map.size());
1340     }
1341 
1342     @Test
1343     public void testToString(){
1344         assumeTrue(isAddSupported());
1345         final MultiValuedMap<K, V> map = makeObject();
1346         map.put((K) "A", (V) "X");
1347         map.put((K) "A", (V) "Y");
1348         map.put((K) "A", (V) "Z");
1349         map.put((K) "B", (V) "U");
1350         map.put((K) "B", (V) "V");
1351         map.put((K) "B", (V) "W");
1352         assertTrue(
1353             "{A=[X, Y, Z], B=[U, V, W]}".equals(map.toString()) ||
1354             "{B=[U, V, W], A=[X, Y, Z]}".equals(map.toString())
1355         );
1356 
1357         final MultiValuedMap<K, V> originalNull = null;
1358         assertThrows(NullPointerException.class, () -> map.putAll(originalNull),
1359                 "expecting NullPointerException");
1360         assertTrue(
1361             "{A=[X, Y, Z], B=[U, V, W]}".equals(map.toString()) ||
1362             "{B=[U, V, W], A=[X, Y, Z]}".equals(map.toString())
1363         );
1364 
1365         map.remove("A");
1366         map.remove("B");
1367         assertEquals("{}", map.toString());
1368     }
1369 
1370     @Test
1371     @SuppressWarnings("unchecked")
1372     public void testValues() {
1373         final MultiValuedMap<K, V> map = makeFullMap();
1374         final HashSet<V> expected = new HashSet<>();
1375         final int maxK = getSampleKeySize();
1376         final int maxV = getSampleCountPerKey();
1377         for (int k = 0; k < maxK; k++) {
1378             for (int v = 0; v < maxV; v++) {
1379                 expected.add((V) makeValue(k, v));
1380             }
1381         }
1382         final Collection<V> c = map.values();
1383         assertEquals(getSampleTotalValueCount(), c.size());
1384         assertEquals(expected, new HashSet<>(c));
1385     }
1386 
1387 }