1 /*
2  * Copyright (C) 2008 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.truth.Truth.assertThat;
21 import static java.util.Arrays.asList;
22 
23 import com.google.common.annotations.GwtCompatible;
24 import com.google.common.annotations.GwtIncompatible;
25 import com.google.common.collect.testing.ListTestSuiteBuilder;
26 import com.google.common.collect.testing.MinimalCollection;
27 import com.google.common.collect.testing.SetTestSuiteBuilder;
28 import com.google.common.collect.testing.TestStringListGenerator;
29 import com.google.common.collect.testing.TestStringSetGenerator;
30 import com.google.common.collect.testing.features.CollectionFeature;
31 import com.google.common.collect.testing.features.CollectionSize;
32 import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
33 import com.google.common.collect.testing.google.TestStringMultisetGenerator;
34 import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
35 import com.google.common.testing.EqualsTester;
36 import com.google.common.testing.NullPointerTester;
37 import com.google.common.testing.SerializableTester;
38 import java.util.ArrayList;
39 import java.util.Collection;
40 import java.util.HashSet;
41 import java.util.Iterator;
42 import java.util.List;
43 import java.util.Set;
44 import junit.framework.Test;
45 import junit.framework.TestCase;
46 import junit.framework.TestSuite;
47 
48 /**
49  * Tests for {@link ImmutableMultiset}.
50  *
51  * @author Jared Levy
52  */
53 @GwtCompatible(emulated = true)
54 public class ImmutableMultisetTest extends TestCase {
55 
56   @GwtIncompatible // suite // TODO(cpovirk): add to collect/gwt/suites
suite()57   public static Test suite() {
58     TestSuite suite = new TestSuite();
59     suite.addTestSuite(ImmutableMultisetTest.class);
60 
61     suite.addTest(
62         MultisetTestSuiteBuilder.using(
63                 new TestStringMultisetGenerator() {
64                   @Override
65                   protected Multiset<String> create(String[] elements) {
66                     return ImmutableMultiset.copyOf(elements);
67                   }
68                 })
69             .named("ImmutableMultiset")
70             .withFeatures(
71                 CollectionSize.ANY,
72                 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
73                 CollectionFeature.ALLOWS_NULL_QUERIES)
74             .createTestSuite());
75 
76     suite.addTest(
77         SetTestSuiteBuilder.using(
78                 new TestStringSetGenerator() {
79                   @Override
80                   protected Set<String> create(String[] elements) {
81                     return ImmutableMultiset.copyOf(elements).elementSet();
82                   }
83                 })
84             .named("ImmutableMultiset, element set")
85             .withFeatures(
86                 CollectionSize.ANY,
87                 CollectionFeature.SERIALIZABLE,
88                 CollectionFeature.ALLOWS_NULL_QUERIES)
89             .createTestSuite());
90 
91     suite.addTest(
92         ListTestSuiteBuilder.using(
93                 new TestStringListGenerator() {
94                   @Override
95                   protected List<String> create(String[] elements) {
96                     return ImmutableMultiset.copyOf(elements).asList();
97                   }
98 
99                   @Override
100                   public List<String> order(List<String> insertionOrder) {
101                     List<String> order = new ArrayList<>();
102                     for (String s : insertionOrder) {
103                       int index = order.indexOf(s);
104                       if (index == -1) {
105                         order.add(s);
106                       } else {
107                         order.add(index, s);
108                       }
109                     }
110                     return order;
111                   }
112                 })
113             .named("ImmutableMultiset.asList")
114             .withFeatures(
115                 CollectionSize.ANY,
116                 CollectionFeature.SERIALIZABLE,
117                 CollectionFeature.ALLOWS_NULL_QUERIES)
118             .createTestSuite());
119 
120     suite.addTest(
121         ListTestSuiteBuilder.using(
122                 new TestStringListGenerator() {
123                   @Override
124                   protected List<String> create(String[] elements) {
125                     Set<String> set = new HashSet<>();
126                     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
127                     for (String s : elements) {
128                       checkArgument(set.add(s));
129                       builder.addCopies(s, 2);
130                     }
131                     ImmutableSet<String> elementSet =
132                         (ImmutableSet<String>) builder.build().elementSet();
133                     return elementSet.asList();
134                   }
135                 })
136             .named("ImmutableMultiset.elementSet.asList")
137             .withFeatures(
138                 CollectionSize.ANY,
139                 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
140                 CollectionFeature.SERIALIZABLE,
141                 CollectionFeature.ALLOWS_NULL_QUERIES)
142             .createTestSuite());
143 
144     return suite;
145   }
146 
testCreation_noArgs()147   public void testCreation_noArgs() {
148     Multiset<String> multiset = ImmutableMultiset.of();
149     assertTrue(multiset.isEmpty());
150   }
151 
testCreation_oneElement()152   public void testCreation_oneElement() {
153     Multiset<String> multiset = ImmutableMultiset.of("a");
154     assertEquals(HashMultiset.create(asList("a")), multiset);
155   }
156 
testCreation_twoElements()157   public void testCreation_twoElements() {
158     Multiset<String> multiset = ImmutableMultiset.of("a", "b");
159     assertEquals(HashMultiset.create(asList("a", "b")), multiset);
160   }
161 
testCreation_threeElements()162   public void testCreation_threeElements() {
163     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c");
164     assertEquals(HashMultiset.create(asList("a", "b", "c")), multiset);
165   }
166 
testCreation_fourElements()167   public void testCreation_fourElements() {
168     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d");
169     assertEquals(HashMultiset.create(asList("a", "b", "c", "d")), multiset);
170   }
171 
testCreation_fiveElements()172   public void testCreation_fiveElements() {
173     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d", "e");
174     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e")), multiset);
175   }
176 
testCreation_sixElements()177   public void testCreation_sixElements() {
178     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d", "e", "f");
179     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e", "f")), multiset);
180   }
181 
testCreation_sevenElements()182   public void testCreation_sevenElements() {
183     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d", "e", "f", "g");
184     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e", "f", "g")), multiset);
185   }
186 
testCreation_emptyArray()187   public void testCreation_emptyArray() {
188     String[] array = new String[0];
189     Multiset<String> multiset = ImmutableMultiset.copyOf(array);
190     assertTrue(multiset.isEmpty());
191   }
192 
testCreation_arrayOfOneElement()193   public void testCreation_arrayOfOneElement() {
194     String[] array = new String[] {"a"};
195     Multiset<String> multiset = ImmutableMultiset.copyOf(array);
196     assertEquals(HashMultiset.create(asList("a")), multiset);
197   }
198 
testCreation_arrayOfArray()199   public void testCreation_arrayOfArray() {
200     String[] array = new String[] {"a"};
201     Multiset<String[]> multiset = ImmutableMultiset.<String[]>of(array);
202     Multiset<String[]> expected = HashMultiset.create();
203     expected.add(array);
204     assertEquals(expected, multiset);
205   }
206 
testCreation_arrayContainingOnlyNull()207   public void testCreation_arrayContainingOnlyNull() {
208     String[] array = new String[] {null};
209     try {
210       ImmutableMultiset.copyOf(array);
211       fail();
212     } catch (NullPointerException expected) {
213     }
214   }
215 
testCopyOf_collection_empty()216   public void testCopyOf_collection_empty() {
217     // "<String>" is required to work around a javac 1.5 bug.
218     Collection<String> c = MinimalCollection.<String>of();
219     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
220     assertTrue(multiset.isEmpty());
221   }
222 
testCopyOf_collection_oneElement()223   public void testCopyOf_collection_oneElement() {
224     Collection<String> c = MinimalCollection.of("a");
225     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
226     assertEquals(HashMultiset.create(asList("a")), multiset);
227   }
228 
testCopyOf_collection_general()229   public void testCopyOf_collection_general() {
230     Collection<String> c = MinimalCollection.of("a", "b", "a");
231     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
232     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
233   }
234 
testCopyOf_collectionContainingNull()235   public void testCopyOf_collectionContainingNull() {
236     Collection<String> c = MinimalCollection.of("a", null, "b");
237     try {
238       ImmutableMultiset.copyOf(c);
239       fail();
240     } catch (NullPointerException expected) {
241     }
242   }
243 
testCopyOf_multiset_empty()244   public void testCopyOf_multiset_empty() {
245     Multiset<String> c = HashMultiset.create();
246     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
247     assertTrue(multiset.isEmpty());
248   }
249 
testCopyOf_multiset_oneElement()250   public void testCopyOf_multiset_oneElement() {
251     Multiset<String> c = HashMultiset.create(asList("a"));
252     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
253     assertEquals(HashMultiset.create(asList("a")), multiset);
254   }
255 
testCopyOf_multiset_general()256   public void testCopyOf_multiset_general() {
257     Multiset<String> c = HashMultiset.create(asList("a", "b", "a"));
258     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
259     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
260   }
261 
testCopyOf_multisetContainingNull()262   public void testCopyOf_multisetContainingNull() {
263     Multiset<String> c = HashMultiset.create(asList("a", null, "b"));
264     try {
265       ImmutableMultiset.copyOf(c);
266       fail();
267     } catch (NullPointerException expected) {
268     }
269   }
270 
testCopyOf_iterator_empty()271   public void testCopyOf_iterator_empty() {
272     Iterator<String> iterator = Iterators.emptyIterator();
273     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
274     assertTrue(multiset.isEmpty());
275   }
276 
testCopyOf_iterator_oneElement()277   public void testCopyOf_iterator_oneElement() {
278     Iterator<String> iterator = Iterators.singletonIterator("a");
279     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
280     assertEquals(HashMultiset.create(asList("a")), multiset);
281   }
282 
testCopyOf_iterator_general()283   public void testCopyOf_iterator_general() {
284     Iterator<String> iterator = asList("a", "b", "a").iterator();
285     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
286     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
287   }
288 
testCopyOf_iteratorContainingNull()289   public void testCopyOf_iteratorContainingNull() {
290     Iterator<String> iterator = asList("a", null, "b").iterator();
291     try {
292       ImmutableMultiset.copyOf(iterator);
293       fail();
294     } catch (NullPointerException expected) {
295     }
296   }
297 
298   private static class CountingIterable implements Iterable<String> {
299     int count = 0;
300 
301     @Override
iterator()302     public Iterator<String> iterator() {
303       count++;
304       return asList("a", "b", "a").iterator();
305     }
306   }
307 
testCopyOf_plainIterable()308   public void testCopyOf_plainIterable() {
309     CountingIterable iterable = new CountingIterable();
310     Multiset<String> multiset = ImmutableMultiset.copyOf(iterable);
311     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
312     assertEquals(1, iterable.count);
313   }
314 
testCopyOf_hashMultiset()315   public void testCopyOf_hashMultiset() {
316     Multiset<String> iterable = HashMultiset.create(asList("a", "b", "a"));
317     Multiset<String> multiset = ImmutableMultiset.copyOf(iterable);
318     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
319   }
320 
testCopyOf_treeMultiset()321   public void testCopyOf_treeMultiset() {
322     Multiset<String> iterable = TreeMultiset.create(asList("a", "b", "a"));
323     Multiset<String> multiset = ImmutableMultiset.copyOf(iterable);
324     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
325   }
326 
testCopyOf_shortcut_empty()327   public void testCopyOf_shortcut_empty() {
328     Collection<String> c = ImmutableMultiset.of();
329     assertSame(c, ImmutableMultiset.copyOf(c));
330   }
331 
testCopyOf_shortcut_singleton()332   public void testCopyOf_shortcut_singleton() {
333     Collection<String> c = ImmutableMultiset.of("a");
334     assertSame(c, ImmutableMultiset.copyOf(c));
335   }
336 
testCopyOf_shortcut_immutableMultiset()337   public void testCopyOf_shortcut_immutableMultiset() {
338     Collection<String> c = ImmutableMultiset.of("a", "b", "c");
339     assertSame(c, ImmutableMultiset.copyOf(c));
340   }
341 
testBuilderAdd()342   public void testBuilderAdd() {
343     ImmutableMultiset<String> multiset =
344         new ImmutableMultiset.Builder<String>().add("a").add("b").add("a").add("c").build();
345     assertEquals(HashMultiset.create(asList("a", "b", "a", "c")), multiset);
346   }
347 
testBuilderAddAll()348   public void testBuilderAddAll() {
349     List<String> a = asList("a", "b");
350     List<String> b = asList("c", "d");
351     ImmutableMultiset<String> multiset =
352         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
353     assertEquals(HashMultiset.create(asList("a", "b", "c", "d")), multiset);
354   }
355 
testBuilderAddAllHashMultiset()356   public void testBuilderAddAllHashMultiset() {
357     Multiset<String> a = HashMultiset.create(asList("a", "b", "b"));
358     Multiset<String> b = HashMultiset.create(asList("c", "b"));
359     ImmutableMultiset<String> multiset =
360         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
361     assertEquals(HashMultiset.create(asList("a", "b", "b", "b", "c")), multiset);
362   }
363 
testBuilderAddAllImmutableMultiset()364   public void testBuilderAddAllImmutableMultiset() {
365     Multiset<String> a = ImmutableMultiset.of("a", "b", "b");
366     Multiset<String> b = ImmutableMultiset.of("c", "b");
367     ImmutableMultiset<String> multiset =
368         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
369     assertEquals(HashMultiset.create(asList("a", "b", "b", "b", "c")), multiset);
370   }
371 
testBuilderAddAllTreeMultiset()372   public void testBuilderAddAllTreeMultiset() {
373     Multiset<String> a = TreeMultiset.create(asList("a", "b", "b"));
374     Multiset<String> b = TreeMultiset.create(asList("c", "b"));
375     ImmutableMultiset<String> multiset =
376         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
377     assertEquals(HashMultiset.create(asList("a", "b", "b", "b", "c")), multiset);
378   }
379 
testBuilderAddAllIterator()380   public void testBuilderAddAllIterator() {
381     Iterator<String> iterator = asList("a", "b", "a", "c").iterator();
382     ImmutableMultiset<String> multiset =
383         new ImmutableMultiset.Builder<String>().addAll(iterator).build();
384     assertEquals(HashMultiset.create(asList("a", "b", "a", "c")), multiset);
385   }
386 
testBuilderAddCopies()387   public void testBuilderAddCopies() {
388     ImmutableMultiset<String> multiset =
389         new ImmutableMultiset.Builder<String>()
390             .addCopies("a", 2)
391             .addCopies("b", 3)
392             .addCopies("c", 0)
393             .build();
394     assertEquals(HashMultiset.create(asList("a", "a", "b", "b", "b")), multiset);
395   }
396 
testBuilderSetCount()397   public void testBuilderSetCount() {
398     ImmutableMultiset<String> multiset =
399         new ImmutableMultiset.Builder<String>().add("a").setCount("a", 2).setCount("b", 3).build();
400     assertEquals(HashMultiset.create(asList("a", "a", "b", "b", "b")), multiset);
401   }
402 
testBuilderAddHandlesNullsCorrectly()403   public void testBuilderAddHandlesNullsCorrectly() {
404     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
405     try {
406       builder.add((String) null);
407       fail("expected NullPointerException");
408     } catch (NullPointerException expected) {
409     }
410   }
411 
testBuilderAddAllHandlesNullsCorrectly()412   public void testBuilderAddAllHandlesNullsCorrectly() {
413     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
414     try {
415       builder.addAll((Collection<String>) null);
416       fail("expected NullPointerException");
417     } catch (NullPointerException expected) {
418     }
419 
420     builder = ImmutableMultiset.builder();
421     List<String> listWithNulls = asList("a", null, "b");
422     try {
423       builder.addAll(listWithNulls);
424       fail("expected NullPointerException");
425     } catch (NullPointerException expected) {
426     }
427 
428     builder = ImmutableMultiset.builder();
429     Multiset<String> multisetWithNull = LinkedHashMultiset.create(asList("a", null, "b"));
430     try {
431       builder.addAll(multisetWithNull);
432       fail("expected NullPointerException");
433     } catch (NullPointerException expected) {
434     }
435   }
436 
testBuilderAddCopiesHandlesNullsCorrectly()437   public void testBuilderAddCopiesHandlesNullsCorrectly() {
438     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
439     try {
440       builder.addCopies(null, 2);
441       fail("expected NullPointerException");
442     } catch (NullPointerException expected) {
443     }
444   }
445 
testBuilderAddCopiesIllegal()446   public void testBuilderAddCopiesIllegal() {
447     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
448     try {
449       builder.addCopies("a", -2);
450       fail("expected IllegalArgumentException");
451     } catch (IllegalArgumentException expected) {
452     }
453   }
454 
testBuilderSetCountHandlesNullsCorrectly()455   public void testBuilderSetCountHandlesNullsCorrectly() {
456     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
457     try {
458       builder.setCount(null, 2);
459       fail("expected NullPointerException");
460     } catch (NullPointerException expected) {
461     }
462   }
463 
testBuilderSetCountIllegal()464   public void testBuilderSetCountIllegal() {
465     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
466     try {
467       builder.setCount("a", -2);
468       fail("expected IllegalArgumentException");
469     } catch (IllegalArgumentException expected) {
470     }
471   }
472 
473   @GwtIncompatible // NullPointerTester
testNullPointers()474   public void testNullPointers() {
475     NullPointerTester tester = new NullPointerTester();
476     tester.testAllPublicStaticMethods(ImmutableMultiset.class);
477   }
478 
479   @GwtIncompatible // SerializableTester
testSerialization_empty()480   public void testSerialization_empty() {
481     Collection<String> c = ImmutableMultiset.of();
482     assertSame(c, SerializableTester.reserialize(c));
483   }
484 
485   @GwtIncompatible // SerializableTester
testSerialization_multiple()486   public void testSerialization_multiple() {
487     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
488     Collection<String> copy = SerializableTester.reserializeAndAssert(c);
489     assertThat(copy).containsExactly("a", "a", "b").inOrder();
490   }
491 
492   @GwtIncompatible // SerializableTester
testSerialization_elementSet()493   public void testSerialization_elementSet() {
494     Multiset<String> c = ImmutableMultiset.of("a", "b", "a");
495     Collection<String> copy = LenientSerializableTester.reserializeAndAssertLenient(c.elementSet());
496     assertThat(copy).containsExactly("a", "b").inOrder();
497   }
498 
499   @GwtIncompatible // SerializableTester
testSerialization_entrySet()500   public void testSerialization_entrySet() {
501     Multiset<String> c = ImmutableMultiset.of("a", "b", "c");
502     SerializableTester.reserializeAndAssert(c.entrySet());
503   }
504 
testEquals_immutableMultiset()505   public void testEquals_immutableMultiset() {
506     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
507     assertEquals(c, ImmutableMultiset.of("a", "b", "a"));
508     assertEquals(c, ImmutableMultiset.of("a", "a", "b"));
509     assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b"));
510     assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b", "c", "d"));
511   }
512 
testIterationOrder()513   public void testIterationOrder() {
514     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
515     assertThat(c).containsExactly("a", "a", "b").inOrder();
516     assertThat(ImmutableMultiset.of("c", "b", "a", "c").elementSet())
517         .containsExactly("c", "b", "a")
518         .inOrder();
519   }
520 
testMultisetWrites()521   public void testMultisetWrites() {
522     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "a");
523     UnmodifiableCollectionTests.assertMultisetIsUnmodifiable(multiset, "test");
524   }
525 
testAsList()526   public void testAsList() {
527     ImmutableMultiset<String> multiset = ImmutableMultiset.of("a", "a", "b", "b", "b");
528     ImmutableList<String> list = multiset.asList();
529     assertEquals(ImmutableList.of("a", "a", "b", "b", "b"), list);
530     assertEquals(2, list.indexOf("b"));
531     assertEquals(4, list.lastIndexOf("b"));
532   }
533 
534   @GwtIncompatible // SerializableTester
testSerialization_asList()535   public void testSerialization_asList() {
536     ImmutableMultiset<String> multiset = ImmutableMultiset.of("a", "a", "b", "b", "b");
537     SerializableTester.reserializeAndAssert(multiset.asList());
538   }
539 
testEquals()540   public void testEquals() {
541     new EqualsTester()
542         .addEqualityGroup(ImmutableMultiset.of(), ImmutableMultiset.of())
543         .addEqualityGroup(ImmutableMultiset.of(1), ImmutableMultiset.of(1))
544         .addEqualityGroup(ImmutableMultiset.of(1, 1), ImmutableMultiset.of(1, 1))
545         .addEqualityGroup(ImmutableMultiset.of(1, 2, 1), ImmutableMultiset.of(2, 1, 1))
546         .testEquals();
547   }
548 
testIterationOrderThroughBuilderRemovals()549   public void testIterationOrderThroughBuilderRemovals() {
550     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
551     builder.addCopies("a", 2);
552     builder.add("b");
553     builder.add("c");
554     builder.setCount("b", 0);
555     ImmutableMultiset<String> multiset = builder.build();
556     assertThat(multiset.elementSet()).containsExactly("a", "c").inOrder();
557     builder.add("b");
558     assertThat(builder.build().elementSet()).containsExactly("a", "c", "b").inOrder();
559     assertThat(multiset.elementSet()).containsExactly("a", "c").inOrder();
560   }
561 }
562