• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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.collect.Iterables.unmodifiableIterable;
20 import static com.google.common.collect.Sets.newEnumSet;
21 import static com.google.common.collect.Sets.newHashSet;
22 import static com.google.common.collect.Sets.newLinkedHashSet;
23 import static com.google.common.collect.Sets.powerSet;
24 import static com.google.common.collect.Sets.unmodifiableNavigableSet;
25 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
26 import static com.google.common.truth.Truth.assertThat;
27 import static java.io.ObjectStreamConstants.TC_REFERENCE;
28 import static java.io.ObjectStreamConstants.baseWireHandle;
29 import static java.util.Collections.emptySet;
30 import static java.util.Collections.singleton;
31 
32 import com.google.common.annotations.GwtCompatible;
33 import com.google.common.annotations.GwtIncompatible;
34 import com.google.common.base.Predicate;
35 import com.google.common.collect.testing.AnEnum;
36 import com.google.common.collect.testing.IteratorTester;
37 import com.google.common.collect.testing.MinimalIterable;
38 import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
39 import com.google.common.collect.testing.SafeTreeSet;
40 import com.google.common.collect.testing.SetTestSuiteBuilder;
41 import com.google.common.collect.testing.TestEnumSetGenerator;
42 import com.google.common.collect.testing.TestStringSetGenerator;
43 import com.google.common.collect.testing.features.CollectionFeature;
44 import com.google.common.collect.testing.features.CollectionSize;
45 import com.google.common.collect.testing.features.SetFeature;
46 import com.google.common.testing.EqualsTester;
47 import com.google.common.testing.NullPointerTester;
48 import com.google.common.testing.SerializableTester;
49 import java.io.ByteArrayInputStream;
50 import java.io.ByteArrayOutputStream;
51 import java.io.IOException;
52 import java.io.ObjectInputStream;
53 import java.io.ObjectOutputStream;
54 import java.io.Serializable;
55 import java.nio.ByteBuffer;
56 import java.util.ArrayList;
57 import java.util.Arrays;
58 import java.util.Collection;
59 import java.util.Collections;
60 import java.util.Comparator;
61 import java.util.EnumSet;
62 import java.util.HashMap;
63 import java.util.HashSet;
64 import java.util.Iterator;
65 import java.util.LinkedHashMap;
66 import java.util.LinkedHashSet;
67 import java.util.List;
68 import java.util.Map;
69 import java.util.NavigableSet;
70 import java.util.NoSuchElementException;
71 import java.util.Set;
72 import java.util.SortedSet;
73 import java.util.TreeSet;
74 import java.util.concurrent.CopyOnWriteArraySet;
75 import junit.framework.Test;
76 import junit.framework.TestCase;
77 import junit.framework.TestSuite;
78 import org.checkerframework.checker.nullness.compatqual.NullableDecl;
79 
80 /**
81  * Unit test for {@code Sets}.
82  *
83  * @author Kevin Bourrillion
84  * @author Jared Levy
85  */
86 @GwtCompatible(emulated = true)
87 public class SetsTest extends TestCase {
88 
89   private static final IteratorTester.KnownOrder KNOWN_ORDER =
90       IteratorTester.KnownOrder.KNOWN_ORDER;
91 
92   private static final Collection<Integer> EMPTY_COLLECTION = Arrays.<Integer>asList();
93 
94   private static final Collection<Integer> SOME_COLLECTION = Arrays.asList(0, 1, 1);
95 
96   private static final Iterable<Integer> SOME_ITERABLE =
97       new Iterable<Integer>() {
98         @Override
99         public Iterator<Integer> iterator() {
100           return SOME_COLLECTION.iterator();
101         }
102       };
103 
104   private static final List<Integer> LONGER_LIST = Arrays.asList(8, 6, 7, 5, 3, 0, 9);
105 
106   private static final Comparator<Integer> SOME_COMPARATOR = Collections.reverseOrder();
107 
108   @GwtIncompatible // suite
suite()109   public static Test suite() {
110     TestSuite suite = new TestSuite();
111     suite.addTestSuite(SetsTest.class);
112 
113     suite.addTest(
114         SetTestSuiteBuilder.using(
115                 new TestStringSetGenerator() {
116                   @Override
117                   protected Set<String> create(String[] elements) {
118                     return Sets.newConcurrentHashSet(Arrays.asList(elements));
119                   }
120                 })
121             .named("Sets.newConcurrentHashSet")
122             .withFeatures(CollectionSize.ANY, SetFeature.GENERAL_PURPOSE)
123             .createTestSuite());
124 
125     suite.addTest(
126         SetTestSuiteBuilder.using(
127                 new TestStringSetGenerator() {
128                   @Override
129                   protected Set<String> create(String[] elements) {
130                     int size = elements.length;
131                     // Remove last element, if size > 1
132                     Set<String> set1 =
133                         (size > 1)
134                             ? Sets.newHashSet(Arrays.asList(elements).subList(0, size - 1))
135                             : Sets.newHashSet(elements);
136                     // Remove first element, if size > 0
137                     Set<String> set2 =
138                         (size > 0)
139                             ? Sets.newHashSet(Arrays.asList(elements).subList(1, size))
140                             : Sets.<String>newHashSet();
141                     return Sets.union(set1, set2);
142                   }
143                 })
144             .named("Sets.union")
145             .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES)
146             .createTestSuite());
147 
148     suite.addTest(
149         SetTestSuiteBuilder.using(
150                 new TestStringSetGenerator() {
151                   @Override
152                   protected Set<String> create(String[] elements) {
153                     Set<String> set1 = Sets.newHashSet(elements);
154                     set1.add(samples().e3());
155                     Set<String> set2 = Sets.newHashSet(elements);
156                     set2.add(samples().e4());
157                     return Sets.intersection(set1, set2);
158                   }
159                 })
160             .named("Sets.intersection")
161             .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES)
162             .createTestSuite());
163 
164     suite.addTest(
165         SetTestSuiteBuilder.using(
166                 new TestStringSetGenerator() {
167                   @Override
168                   protected Set<String> create(String[] elements) {
169                     Set<String> set1 = Sets.newHashSet(elements);
170                     set1.add(samples().e3());
171                     Set<String> set2 = Sets.newHashSet(samples().e3());
172                     return Sets.difference(set1, set2);
173                   }
174                 })
175             .named("Sets.difference")
176             .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES)
177             .createTestSuite());
178 
179     suite.addTest(
180         SetTestSuiteBuilder.using(
181                 new TestEnumSetGenerator() {
182                   @Override
183                   protected Set<AnEnum> create(AnEnum[] elements) {
184                     AnEnum[] otherElements = new AnEnum[elements.length - 1];
185                     System.arraycopy(elements, 1, otherElements, 0, otherElements.length);
186                     return Sets.immutableEnumSet(elements[0], otherElements);
187                   }
188                 })
189             .named("Sets.immutableEnumSet")
190             .withFeatures(
191                 CollectionSize.ONE, CollectionSize.SEVERAL, CollectionFeature.ALLOWS_NULL_QUERIES)
192             .createTestSuite());
193 
194     suite.addTest(
195         NavigableSetTestSuiteBuilder.using(
196                 new TestStringSetGenerator() {
197                   @Override
198                   protected Set<String> create(String[] elements) {
199                     SafeTreeSet<String> set = new SafeTreeSet<>(Arrays.asList(elements));
200                     return Sets.unmodifiableNavigableSet(set);
201                   }
202 
203                   @Override
204                   public List<String> order(List<String> insertionOrder) {
205                     return Ordering.natural().sortedCopy(insertionOrder);
206                   }
207                 })
208             .named("Sets.unmodifiableNavigableSet[TreeSet]")
209             .withFeatures(
210                 CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, CollectionFeature.SERIALIZABLE)
211             .createTestSuite());
212 
213     suite.addTest(testsForFilter());
214     suite.addTest(testsForFilterNoNulls());
215     suite.addTest(testsForFilterFiltered());
216 
217     return suite;
218   }
219 
220   @GwtIncompatible // suite
testsForFilter()221   private static Test testsForFilter() {
222     return SetTestSuiteBuilder.using(
223             new TestStringSetGenerator() {
224               @Override
225               public Set<String> create(String[] elements) {
226                 Set<String> unfiltered = Sets.newLinkedHashSet();
227                 unfiltered.add("yyy");
228                 Collections.addAll(unfiltered, elements);
229                 unfiltered.add("zzz");
230                 return Sets.filter(unfiltered, Collections2Test.NOT_YYY_ZZZ);
231               }
232             })
233         .named("Sets.filter")
234         .withFeatures(
235             CollectionFeature.SUPPORTS_ADD,
236             CollectionFeature.SUPPORTS_REMOVE,
237             CollectionFeature.ALLOWS_NULL_VALUES,
238             CollectionFeature.KNOWN_ORDER,
239             CollectionSize.ANY)
240         .createTestSuite();
241   }
242 
243   @GwtIncompatible // suite
244   private static Test testsForFilterNoNulls() {
245     TestSuite suite = new TestSuite();
246     suite.addTest(
247         SetTestSuiteBuilder.using(
248                 new TestStringSetGenerator() {
249                   @Override
250                   public Set<String> create(String[] elements) {
251                     Set<String> unfiltered = Sets.newLinkedHashSet();
252                     unfiltered.add("yyy");
253                     unfiltered.addAll(ImmutableList.copyOf(elements));
254                     unfiltered.add("zzz");
255                     return Sets.filter(unfiltered, Collections2Test.LENGTH_1);
256                   }
257                 })
258             .named("Sets.filter, no nulls")
259             .withFeatures(
260                 CollectionFeature.SUPPORTS_ADD,
261                 CollectionFeature.SUPPORTS_REMOVE,
262                 CollectionFeature.KNOWN_ORDER,
263                 CollectionSize.ANY,
264                 CollectionFeature.ALLOWS_NULL_QUERIES)
265             .createTestSuite());
266     suite.addTest(
267         NavigableSetTestSuiteBuilder.using(
268                 new TestStringSetGenerator() {
269                   @Override
270                   public NavigableSet<String> create(String[] elements) {
271                     NavigableSet<String> unfiltered = Sets.newTreeSet();
272                     unfiltered.add("yyy");
273                     unfiltered.addAll(ImmutableList.copyOf(elements));
274                     unfiltered.add("zzz");
275                     return Sets.filter(unfiltered, Collections2Test.LENGTH_1);
276                   }
277 
278                   @Override
279                   public List<String> order(List<String> insertionOrder) {
280                     return Ordering.natural().sortedCopy(insertionOrder);
281                   }
282                 })
283             .named("Sets.filter[NavigableSet]")
284             .withFeatures(
285                 CollectionFeature.SUPPORTS_ADD,
286                 CollectionFeature.SUPPORTS_REMOVE,
287                 CollectionFeature.KNOWN_ORDER,
288                 CollectionSize.ANY,
289                 CollectionFeature.ALLOWS_NULL_QUERIES)
290             .createTestSuite());
291     return suite;
292   }
293 
294   @GwtIncompatible // suite
295   private static Test testsForFilterFiltered() {
296     return SetTestSuiteBuilder.using(
297             new TestStringSetGenerator() {
298               @Override
299               public Set<String> create(String[] elements) {
300                 Set<String> unfiltered = Sets.newLinkedHashSet();
301                 unfiltered.add("yyy");
302                 unfiltered.addAll(ImmutableList.copyOf(elements));
303                 unfiltered.add("zzz");
304                 unfiltered.add("abc");
305                 return Sets.filter(
306                     Sets.filter(unfiltered, Collections2Test.LENGTH_1),
307                     Collections2Test.NOT_YYY_ZZZ);
308               }
309             })
310         .named("Sets.filter, filtered input")
311         .withFeatures(
312             CollectionFeature.SUPPORTS_ADD,
313             CollectionFeature.SUPPORTS_REMOVE,
314             CollectionFeature.KNOWN_ORDER,
315             CollectionSize.ANY,
316             CollectionFeature.ALLOWS_NULL_QUERIES)
317         .createTestSuite();
318   }
319 
320   private enum SomeEnum {
321     A,
322     B,
323     C,
324     D
325   }
326 
327   public void testImmutableEnumSet() {
328     Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B);
329 
330     assertThat(units).containsExactly(SomeEnum.B, SomeEnum.D).inOrder();
331     try {
332       units.remove(SomeEnum.B);
333       fail("ImmutableEnumSet should throw an exception on remove()");
334     } catch (UnsupportedOperationException expected) {
335     }
336     try {
337       units.add(SomeEnum.C);
338       fail("ImmutableEnumSet should throw an exception on add()");
339     } catch (UnsupportedOperationException expected) {
340     }
341   }
342 
343   @GwtIncompatible // SerializableTester
344   public void testImmutableEnumSet_serialized() {
345     Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B);
346 
347     assertThat(units).containsExactly(SomeEnum.B, SomeEnum.D).inOrder();
348 
349     Set<SomeEnum> copy = SerializableTester.reserializeAndAssert(units);
350     assertTrue(copy instanceof ImmutableEnumSet);
351   }
352 
353   public void testImmutableEnumSet_fromIterable() {
354     ImmutableSet<SomeEnum> none = Sets.immutableEnumSet(MinimalIterable.<SomeEnum>of());
355     assertThat(none).isEmpty();
356 
357     ImmutableSet<SomeEnum> one = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.B));
358     assertThat(one).contains(SomeEnum.B);
359 
360     ImmutableSet<SomeEnum> two = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.D, SomeEnum.B));
361     assertThat(two).containsExactly(SomeEnum.B, SomeEnum.D).inOrder();
362   }
363 
364   @GwtIncompatible // java serialization not supported in GWT.
365   public void testImmutableEnumSet_deserializationMakesDefensiveCopy() throws Exception {
366     ImmutableSet<SomeEnum> original = Sets.immutableEnumSet(SomeEnum.A, SomeEnum.B);
367     int handleOffset = 6;
368     byte[] serializedForm = serializeWithBackReference(original, handleOffset);
369     ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(serializedForm));
370 
371     ImmutableSet<?> deserialized = (ImmutableSet<?>) in.readObject();
372     EnumSet<?> delegate = (EnumSet<?>) in.readObject();
373 
374     assertEquals(original, deserialized);
375     assertTrue(delegate.remove(SomeEnum.A));
376     assertTrue(deserialized.contains(SomeEnum.A));
377   }
378 
379   @GwtIncompatible // java serialization not supported in GWT.
380   private static byte[] serializeWithBackReference(Object original, int handleOffset)
381       throws IOException {
382     ByteArrayOutputStream bos = new ByteArrayOutputStream();
383     ObjectOutputStream out = new ObjectOutputStream(bos);
384 
385     out.writeObject(original);
386 
387     byte[] handle = toByteArray(baseWireHandle + handleOffset);
388     byte[] ref = prepended(TC_REFERENCE, handle);
389     bos.write(ref);
390 
391     return bos.toByteArray();
392   }
393 
394   private static byte[] prepended(byte b, byte[] array) {
395     byte[] out = new byte[array.length + 1];
396     out[0] = b;
397     System.arraycopy(array, 0, out, 1, array.length);
398     return out;
399   }
400 
401   @GwtIncompatible // java.nio.ByteBuffer
402   private static byte[] toByteArray(int h) {
403     return ByteBuffer.allocate(4).putInt(h).array();
404   }
405 
406   public void testNewEnumSet_empty() {
407     EnumSet<SomeEnum> copy = newEnumSet(Collections.<SomeEnum>emptySet(), SomeEnum.class);
408     assertEquals(EnumSet.noneOf(SomeEnum.class), copy);
409   }
410 
411   public void testNewEnumSet_enumSet() {
412     EnumSet<SomeEnum> set = EnumSet.of(SomeEnum.A, SomeEnum.D);
413     assertEquals(set, newEnumSet(set, SomeEnum.class));
414   }
415 
416   public void testNewEnumSet_collection() {
417     Set<SomeEnum> set = ImmutableSet.of(SomeEnum.B, SomeEnum.C);
418     assertEquals(set, newEnumSet(set, SomeEnum.class));
419   }
420 
421   public void testNewEnumSet_iterable() {
422     Set<SomeEnum> set = ImmutableSet.of(SomeEnum.A, SomeEnum.B, SomeEnum.C);
423     assertEquals(set, newEnumSet(unmodifiableIterable(set), SomeEnum.class));
424   }
425 
426   public void testNewHashSetEmpty() {
427     HashSet<Integer> set = Sets.newHashSet();
428     verifySetContents(set, EMPTY_COLLECTION);
429   }
430 
431   public void testNewHashSetVarArgs() {
432     HashSet<Integer> set = Sets.newHashSet(0, 1, 1);
433     verifySetContents(set, Arrays.asList(0, 1));
434   }
435 
436   public void testNewHashSetFromCollection() {
437     HashSet<Integer> set = Sets.newHashSet(SOME_COLLECTION);
438     verifySetContents(set, SOME_COLLECTION);
439   }
440 
441   public void testNewHashSetFromIterable() {
442     HashSet<Integer> set = Sets.newHashSet(SOME_ITERABLE);
443     verifySetContents(set, SOME_ITERABLE);
444   }
445 
446   public void testNewHashSetWithExpectedSizeSmall() {
447     HashSet<Integer> set = Sets.newHashSetWithExpectedSize(0);
448     verifySetContents(set, EMPTY_COLLECTION);
449   }
450 
451   public void testNewHashSetWithExpectedSizeLarge() {
452     HashSet<Integer> set = Sets.newHashSetWithExpectedSize(1000);
453     verifySetContents(set, EMPTY_COLLECTION);
454   }
455 
456   public void testNewHashSetFromIterator() {
457     HashSet<Integer> set = Sets.newHashSet(SOME_COLLECTION.iterator());
458     verifySetContents(set, SOME_COLLECTION);
459   }
460 
461   public void testNewConcurrentHashSetEmpty() {
462     Set<Integer> set = Sets.newConcurrentHashSet();
463     verifySetContents(set, EMPTY_COLLECTION);
464   }
465 
466   public void testNewConcurrentHashSetFromCollection() {
467     Set<Integer> set = Sets.newConcurrentHashSet(SOME_COLLECTION);
468     verifySetContents(set, SOME_COLLECTION);
469   }
470 
471   public void testNewLinkedHashSetEmpty() {
472     LinkedHashSet<Integer> set = Sets.newLinkedHashSet();
473     verifyLinkedHashSetContents(set, EMPTY_COLLECTION);
474   }
475 
476   public void testNewLinkedHashSetFromCollection() {
477     LinkedHashSet<Integer> set = Sets.newLinkedHashSet(LONGER_LIST);
478     verifyLinkedHashSetContents(set, LONGER_LIST);
479   }
480 
481   public void testNewLinkedHashSetFromIterable() {
482     LinkedHashSet<Integer> set =
483         Sets.newLinkedHashSet(
484             new Iterable<Integer>() {
485               @Override
486               public Iterator<Integer> iterator() {
487                 return LONGER_LIST.iterator();
488               }
489             });
490     verifyLinkedHashSetContents(set, LONGER_LIST);
491   }
492 
493   public void testNewLinkedHashSetWithExpectedSizeSmall() {
494     LinkedHashSet<Integer> set = Sets.newLinkedHashSetWithExpectedSize(0);
495     verifySetContents(set, EMPTY_COLLECTION);
496   }
497 
498   public void testNewLinkedHashSetWithExpectedSizeLarge() {
499     LinkedHashSet<Integer> set = Sets.newLinkedHashSetWithExpectedSize(1000);
500     verifySetContents(set, EMPTY_COLLECTION);
501   }
502 
503   public void testNewTreeSetEmpty() {
504     TreeSet<Integer> set = Sets.newTreeSet();
505     verifySortedSetContents(set, EMPTY_COLLECTION, null);
506   }
507 
508   public void testNewTreeSetEmptyDerived() {
509     TreeSet<Derived> set = Sets.newTreeSet();
510     assertTrue(set.isEmpty());
511     set.add(new Derived("foo"));
512     set.add(new Derived("bar"));
513     assertThat(set).containsExactly(new Derived("bar"), new Derived("foo")).inOrder();
514   }
515 
516   public void testNewTreeSetEmptyNonGeneric() {
517     TreeSet<LegacyComparable> set = Sets.newTreeSet();
518     assertTrue(set.isEmpty());
519     set.add(new LegacyComparable("foo"));
520     set.add(new LegacyComparable("bar"));
521     assertThat(set)
522         .containsExactly(new LegacyComparable("bar"), new LegacyComparable("foo"))
523         .inOrder();
524   }
525 
526   public void testNewTreeSetFromCollection() {
527     TreeSet<Integer> set = Sets.newTreeSet(SOME_COLLECTION);
528     verifySortedSetContents(set, SOME_COLLECTION, null);
529   }
530 
531   public void testNewTreeSetFromIterable() {
532     TreeSet<Integer> set = Sets.newTreeSet(SOME_ITERABLE);
533     verifySortedSetContents(set, SOME_ITERABLE, null);
534   }
535 
536   public void testNewTreeSetFromIterableDerived() {
537     Iterable<Derived> iterable = Arrays.asList(new Derived("foo"), new Derived("bar"));
538     TreeSet<Derived> set = Sets.newTreeSet(iterable);
539     assertThat(set).containsExactly(new Derived("bar"), new Derived("foo")).inOrder();
540   }
541 
542   public void testNewTreeSetFromIterableNonGeneric() {
543     Iterable<LegacyComparable> iterable =
544         Arrays.asList(new LegacyComparable("foo"), new LegacyComparable("bar"));
545     TreeSet<LegacyComparable> set = Sets.newTreeSet(iterable);
546     assertThat(set)
547         .containsExactly(new LegacyComparable("bar"), new LegacyComparable("foo"))
548         .inOrder();
549   }
550 
551   public void testNewTreeSetEmptyWithComparator() {
552     TreeSet<Integer> set = Sets.newTreeSet(SOME_COMPARATOR);
553     verifySortedSetContents(set, EMPTY_COLLECTION, SOME_COMPARATOR);
554   }
555 
556   public void testNewIdentityHashSet() {
557     Set<Integer> set = Sets.newIdentityHashSet();
558     Integer value1 = new Integer(12357);
559     Integer value2 = new Integer(12357);
560     assertTrue(set.add(value1));
561     assertFalse(set.contains(value2));
562     assertTrue(set.contains(value1));
563     assertTrue(set.add(value2));
564     assertEquals(2, set.size());
565   }
566 
567   @GwtIncompatible // CopyOnWriteArraySet
568   public void testNewCOWASEmpty() {
569     CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet();
570     verifySetContents(set, EMPTY_COLLECTION);
571   }
572 
573   @GwtIncompatible // CopyOnWriteArraySet
574   public void testNewCOWASFromIterable() {
575     CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet(SOME_ITERABLE);
576     verifySetContents(set, SOME_COLLECTION);
577   }
578 
579   public void testComplementOfEnumSet() {
580     Set<SomeEnum> units = EnumSet.of(SomeEnum.B, SomeEnum.D);
581     EnumSet<SomeEnum> otherUnits = Sets.complementOf(units);
582     verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C));
583   }
584 
585   public void testComplementOfEnumSetWithType() {
586     Set<SomeEnum> units = EnumSet.of(SomeEnum.B, SomeEnum.D);
587     EnumSet<SomeEnum> otherUnits = Sets.complementOf(units, SomeEnum.class);
588     verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C));
589   }
590 
591   public void testComplementOfRegularSet() {
592     Set<SomeEnum> units = Sets.newHashSet(SomeEnum.B, SomeEnum.D);
593     EnumSet<SomeEnum> otherUnits = Sets.complementOf(units);
594     verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C));
595   }
596 
597   public void testComplementOfRegularSetWithType() {
598     Set<SomeEnum> units = Sets.newHashSet(SomeEnum.B, SomeEnum.D);
599     EnumSet<SomeEnum> otherUnits = Sets.complementOf(units, SomeEnum.class);
600     verifySetContents(otherUnits, EnumSet.of(SomeEnum.A, SomeEnum.C));
601   }
602 
603   public void testComplementOfEmptySet() {
604     Set<SomeEnum> noUnits = Collections.emptySet();
605     EnumSet<SomeEnum> allUnits = Sets.complementOf(noUnits, SomeEnum.class);
606     verifySetContents(EnumSet.allOf(SomeEnum.class), allUnits);
607   }
608 
609   public void testComplementOfFullSet() {
610     Set<SomeEnum> allUnits = Sets.newHashSet(SomeEnum.values());
611     EnumSet<SomeEnum> noUnits = Sets.complementOf(allUnits, SomeEnum.class);
612     verifySetContents(noUnits, EnumSet.noneOf(SomeEnum.class));
613   }
614 
615   public void testComplementOfEmptyEnumSetWithoutType() {
616     Set<SomeEnum> noUnits = EnumSet.noneOf(SomeEnum.class);
617     EnumSet<SomeEnum> allUnits = Sets.complementOf(noUnits);
618     verifySetContents(allUnits, EnumSet.allOf(SomeEnum.class));
619   }
620 
621   public void testComplementOfEmptySetWithoutTypeDoesntWork() {
622     Set<SomeEnum> set = Collections.emptySet();
623     try {
624       Sets.complementOf(set);
625       fail();
626     } catch (IllegalArgumentException expected) {
627     }
628   }
629 
630   @GwtIncompatible // NullPointerTester
631   public void testNullPointerExceptions() {
632     new NullPointerTester()
633         .setDefault(Enum.class, SomeEnum.A)
634         .setDefault(Class.class, SomeEnum.class) // for newEnumSet
635         .testAllPublicStaticMethods(Sets.class);
636   }
637 
638   public void testNewSetFromMap() {
639     Set<Integer> set = Sets.newSetFromMap(new HashMap<Integer, Boolean>());
640     set.addAll(SOME_COLLECTION);
641     verifySetContents(set, SOME_COLLECTION);
642   }
643 
644   @GwtIncompatible // SerializableTester
645   public void testNewSetFromMapSerialization() {
646     Set<Integer> set = Sets.newSetFromMap(new LinkedHashMap<Integer, Boolean>());
647     set.addAll(SOME_COLLECTION);
648     Set<Integer> copy = SerializableTester.reserializeAndAssert(set);
649     assertThat(copy).containsExactly(0, 1).inOrder();
650   }
651 
652   public void testNewSetFromMapIllegal() {
653     Map<Integer, Boolean> map = new LinkedHashMap<>();
654     map.put(2, true);
655     try {
656       Sets.newSetFromMap(map);
657       fail();
658     } catch (IllegalArgumentException expected) {
659     }
660   }
661 
662   // TODO: the overwhelming number of suppressions below suggests that maybe
663   // it's not worth having a varargs form of this method at all...
664 
665   /** The 0-ary cartesian product is a single empty list. */
666   @SuppressWarnings("unchecked") // varargs!
667   public void testCartesianProduct_zeroary() {
668     assertThat(Sets.cartesianProduct()).containsExactly(list());
669   }
670 
671   /** A unary cartesian product is one list of size 1 for each element in the input set. */
672   @SuppressWarnings("unchecked") // varargs!
673   public void testCartesianProduct_unary() {
674     assertThat(Sets.cartesianProduct(set(1, 2))).containsExactly(list(1), list(2));
675   }
676 
677   @SuppressWarnings("unchecked") // varargs!
678   public void testCartesianProduct_binary0x0() {
679     Set<Integer> mt = emptySet();
680     assertEmpty(Sets.cartesianProduct(mt, mt));
681   }
682 
683   @SuppressWarnings("unchecked") // varargs!
684   public void testCartesianProduct_binary0x1() {
685     Set<Integer> mt = emptySet();
686     assertEmpty(Sets.cartesianProduct(mt, set(1)));
687   }
688 
689   @SuppressWarnings("unchecked") // varargs!
690   public void testCartesianProduct_binary1x0() {
691     Set<Integer> mt = emptySet();
692     assertEmpty(Sets.cartesianProduct(set(1), mt));
693   }
694 
695   private static void assertEmpty(Set<? extends List<?>> set) {
696     assertTrue(set.isEmpty());
697     assertEquals(0, set.size());
698     assertFalse(set.iterator().hasNext());
699   }
700 
701   @SuppressWarnings("unchecked") // varargs!
702   public void testCartesianProduct_binary1x1() {
703     assertThat(Sets.cartesianProduct(set(1), set(2))).contains(list(1, 2));
704   }
705 
706   @SuppressWarnings("unchecked") // varargs!
707   public void testCartesianProduct_binary1x2() {
708     assertThat(Sets.cartesianProduct(set(1), set(2, 3)))
709         .containsExactly(list(1, 2), list(1, 3))
710         .inOrder();
711   }
712 
713   @SuppressWarnings("unchecked") // varargs!
714   public void testCartesianProduct_binary2x2() {
715     assertThat(Sets.cartesianProduct(set(1, 2), set(3, 4)))
716         .containsExactly(list(1, 3), list(1, 4), list(2, 3), list(2, 4))
717         .inOrder();
718   }
719 
720   @SuppressWarnings("unchecked") // varargs!
721   public void testCartesianProduct_2x2x2() {
722     assertThat(Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1)))
723         .containsExactly(
724             list(0, 0, 0),
725             list(0, 0, 1),
726             list(0, 1, 0),
727             list(0, 1, 1),
728             list(1, 0, 0),
729             list(1, 0, 1),
730             list(1, 1, 0),
731             list(1, 1, 1))
732         .inOrder();
733   }
734 
735   @SuppressWarnings("unchecked") // varargs!
736   public void testCartesianProduct_contains() {
737     Set<List<Integer>> actual = Sets.cartesianProduct(set(1, 2), set(3, 4));
738     assertTrue(actual.contains(list(1, 3)));
739     assertTrue(actual.contains(list(1, 4)));
740     assertTrue(actual.contains(list(2, 3)));
741     assertTrue(actual.contains(list(2, 4)));
742     assertFalse(actual.contains(list(3, 1)));
743   }
744 
745   @SuppressWarnings("unchecked") // varargs!
746   public void testCartesianProduct_unrelatedTypes() {
747     Set<Integer> x = set(1, 2);
748     Set<String> y = set("3", "4");
749 
750     List<Object> exp1 = list((Object) 1, "3");
751     List<Object> exp2 = list((Object) 1, "4");
752     List<Object> exp3 = list((Object) 2, "3");
753     List<Object> exp4 = list((Object) 2, "4");
754 
755     assertThat(Sets.<Object>cartesianProduct(x, y))
756         .containsExactly(exp1, exp2, exp3, exp4)
757         .inOrder();
758   }
759 
760   @SuppressWarnings("unchecked") // varargs!
761   public void testCartesianProductTooBig() {
762     Set<Integer> set = ContiguousSet.create(Range.closed(0, 10000), DiscreteDomain.integers());
763     try {
764       Sets.cartesianProduct(set, set, set, set, set);
765       fail("Expected IAE");
766     } catch (IllegalArgumentException expected) {
767     }
768   }
769 
770   @SuppressWarnings("unchecked") // varargs!
771   public void testCartesianProduct_hashCode() {
772     // Run through the same cartesian products we tested above
773 
774     Set<List<Integer>> degenerate = Sets.cartesianProduct();
775     checkHashCode(degenerate);
776 
777     checkHashCode(Sets.cartesianProduct(set(1, 2)));
778 
779     int num = Integer.MAX_VALUE / 3 * 2; // tickle overflow-related problems
780     checkHashCode(Sets.cartesianProduct(set(1, 2, num)));
781 
782     Set<Integer> mt = emptySet();
783     checkHashCode(Sets.cartesianProduct(mt, mt));
784     checkHashCode(Sets.cartesianProduct(mt, set(num)));
785     checkHashCode(Sets.cartesianProduct(set(num), mt));
786     checkHashCode(Sets.cartesianProduct(set(num), set(1)));
787     checkHashCode(Sets.cartesianProduct(set(1), set(2, num)));
788     checkHashCode(Sets.cartesianProduct(set(1, num), set(2, num - 1)));
789     checkHashCode(Sets.cartesianProduct(set(1, num), set(2, num - 1), set(3, num + 1)));
790 
791     // a bigger one
792     checkHashCode(
793         Sets.cartesianProduct(set(1, num, num + 1), set(2), set(3, num + 2), set(4, 5, 6, 7, 8)));
794   }
795 
796   public void testPowerSetEmpty() {
797     ImmutableSet<Integer> elements = ImmutableSet.of();
798     Set<Set<Integer>> powerSet = powerSet(elements);
799     assertEquals(1, powerSet.size());
800     assertEquals(ImmutableSet.of(ImmutableSet.of()), powerSet);
801     assertEquals(0, powerSet.hashCode());
802   }
803 
804   public void testPowerSetContents() {
805     ImmutableSet<Integer> elements = ImmutableSet.of(1, 2, 3);
806     Set<Set<Integer>> powerSet = powerSet(elements);
807     assertEquals(8, powerSet.size());
808     assertEquals(4 * 1 + 4 * 2 + 4 * 3, powerSet.hashCode());
809 
810     Set<Set<Integer>> expected = newHashSet();
811     expected.add(ImmutableSet.<Integer>of());
812     expected.add(ImmutableSet.of(1));
813     expected.add(ImmutableSet.of(2));
814     expected.add(ImmutableSet.of(3));
815     expected.add(ImmutableSet.of(1, 2));
816     expected.add(ImmutableSet.of(1, 3));
817     expected.add(ImmutableSet.of(2, 3));
818     expected.add(ImmutableSet.of(1, 2, 3));
819 
820     Set<Set<Integer>> almostPowerSet = newHashSet(expected);
821     almostPowerSet.remove(ImmutableSet.of(1, 2, 3));
822     almostPowerSet.add(ImmutableSet.of(1, 2, 4));
823 
824     new EqualsTester()
825         .addEqualityGroup(expected, powerSet)
826         .addEqualityGroup(ImmutableSet.of(1, 2, 3))
827         .addEqualityGroup(almostPowerSet)
828         .testEquals();
829 
830     for (Set<Integer> subset : expected) {
831       assertTrue(powerSet.contains(subset));
832     }
833     assertFalse(powerSet.contains(ImmutableSet.of(1, 2, 4)));
834     assertFalse(powerSet.contains(singleton(null)));
835     assertFalse(powerSet.contains(null));
836     assertFalse(powerSet.contains((Object) "notASet"));
837   }
838 
839   public void testPowerSetIteration_manual() {
840     ImmutableSet<Integer> elements = ImmutableSet.of(1, 2, 3);
841     Set<Set<Integer>> powerSet = powerSet(elements);
842     // The API doesn't promise this iteration order, but it's convenient here.
843     Iterator<Set<Integer>> i = powerSet.iterator();
844     assertEquals(ImmutableSet.of(), i.next());
845     assertEquals(ImmutableSet.of(1), i.next());
846     assertEquals(ImmutableSet.of(2), i.next());
847     assertEquals(ImmutableSet.of(2, 1), i.next());
848     assertEquals(ImmutableSet.of(3), i.next());
849     assertEquals(ImmutableSet.of(3, 1), i.next());
850     assertEquals(ImmutableSet.of(3, 2), i.next());
851     assertEquals(ImmutableSet.of(3, 2, 1), i.next());
852     assertFalse(i.hasNext());
853     try {
854       i.next();
855       fail();
856     } catch (NoSuchElementException expected) {
857     }
858   }
859 
860   @GwtIncompatible // too slow for GWT
861   public void testPowerSetIteration_iteratorTester() {
862     ImmutableSet<Integer> elements = ImmutableSet.of(1, 2);
863 
864     Set<Set<Integer>> expected = newLinkedHashSet();
865     expected.add(ImmutableSet.<Integer>of());
866     expected.add(ImmutableSet.of(1));
867     expected.add(ImmutableSet.of(2));
868     expected.add(ImmutableSet.of(1, 2));
869 
870     final Set<Set<Integer>> powerSet = powerSet(elements);
871     new IteratorTester<Set<Integer>>(6, UNMODIFIABLE, expected, KNOWN_ORDER) {
872       @Override
873       protected Iterator<Set<Integer>> newTargetIterator() {
874         return powerSet.iterator();
875       }
876     }.test();
877   }
878 
879   public void testPowerSetIteration_iteratorTester_fast() {
880     ImmutableSet<Integer> elements = ImmutableSet.of(1, 2);
881 
882     Set<Set<Integer>> expected = newLinkedHashSet();
883     expected.add(ImmutableSet.<Integer>of());
884     expected.add(ImmutableSet.of(1));
885     expected.add(ImmutableSet.of(2));
886     expected.add(ImmutableSet.of(1, 2));
887 
888     final Set<Set<Integer>> powerSet = powerSet(elements);
889     new IteratorTester<Set<Integer>>(4, UNMODIFIABLE, expected, KNOWN_ORDER) {
890       @Override
891       protected Iterator<Set<Integer>> newTargetIterator() {
892         return powerSet.iterator();
893       }
894     }.test();
895   }
896 
897   public void testPowerSetSize() {
898     assertPowerSetSize(1);
899     assertPowerSetSize(2, 'a');
900     assertPowerSetSize(4, 'a', 'b');
901     assertPowerSetSize(8, 'a', 'b', 'c');
902     assertPowerSetSize(16, 'a', 'b', 'd', 'e');
903     assertPowerSetSize(
904         1 << 30, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
905         'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4');
906   }
907 
908   public void testPowerSetCreationErrors() {
909     try {
910       Set<Set<Character>> unused =
911           powerSet(
912               newHashSet(
913                   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
914                   'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5'));
915       fail();
916     } catch (IllegalArgumentException expected) {
917     }
918 
919     try {
920       Set<Set<Integer>> unused = powerSet(ContiguousSet.closed(0, Integer.MAX_VALUE / 2));
921       fail();
922     } catch (IllegalArgumentException expected) {
923     }
924 
925     try {
926       powerSet(singleton(null));
927       fail();
928     } catch (NullPointerException expected) {
929     }
930   }
931 
932   public void testPowerSetEqualsAndHashCode_verifyAgainstHashSet() {
933     ImmutableList<Integer> allElements =
934         ImmutableList.of(
935             4233352, 3284593, 3794208, 3849533, 4013967, 2902658, 1886275, 2131109, 985872,
936             1843868);
937     for (int i = 0; i < allElements.size(); i++) {
938       Set<Integer> elements = newHashSet(allElements.subList(0, i));
939       Set<Set<Integer>> powerSet1 = powerSet(elements);
940       Set<Set<Integer>> powerSet2 = powerSet(elements);
941       new EqualsTester()
942           .addEqualityGroup(powerSet1, powerSet2, toHashSets(powerSet1))
943           .addEqualityGroup(ImmutableSet.of())
944           .addEqualityGroup(ImmutableSet.of(9999999))
945           .addEqualityGroup("notASet")
946           .testEquals();
947       assertEquals(toHashSets(powerSet1).hashCode(), powerSet1.hashCode());
948     }
949   }
950 
951   /**
952    * Test that a hash code miscomputed by "input.hashCode() * tooFarValue / 2" is correct under our
953    * {@code hashCode} implementation.
954    */
955   public void testPowerSetHashCode_inputHashCodeTimesTooFarValueIsZero() {
956     Set<Object> sumToEighthMaxIntElements =
957         newHashSet(objectWithHashCode(1 << 29), objectWithHashCode(0));
958     assertPowerSetHashCode(1 << 30, sumToEighthMaxIntElements);
959 
960     Set<Object> sumToQuarterMaxIntElements =
961         newHashSet(objectWithHashCode(1 << 30), objectWithHashCode(0));
962     assertPowerSetHashCode(1 << 31, sumToQuarterMaxIntElements);
963   }
964 
965   public void testPowerSetShowOff() {
966     Set<Object> zero = ImmutableSet.of();
967     Set<Set<Object>> one = powerSet(zero);
968     Set<Set<Set<Object>>> two = powerSet(one);
969     Set<Set<Set<Set<Object>>>> four = powerSet(two);
970     Set<Set<Set<Set<Set<Object>>>>> sixteen = powerSet(four);
971     Set<Set<Set<Set<Set<Set<Object>>>>>> sixtyFiveThousandish = powerSet(sixteen);
972     assertEquals(1 << 16, sixtyFiveThousandish.size());
973 
974     assertTrue(powerSet(makeSetOfZeroToTwentyNine()).contains(makeSetOfZeroToTwentyNine()));
975     assertFalse(powerSet(makeSetOfZeroToTwentyNine()).contains(ImmutableSet.of(30)));
976   }
977 
978   private static Set<Integer> makeSetOfZeroToTwentyNine() {
979     // TODO: use Range once it's publicly available
980     Set<Integer> zeroToTwentyNine = newHashSet();
981     for (int i = 0; i < 30; i++) {
982       zeroToTwentyNine.add(i);
983     }
984     return zeroToTwentyNine;
985   }
986 
987   private static <E> Set<Set<E>> toHashSets(Set<Set<E>> powerSet) {
988     Set<Set<E>> result = newHashSet();
989     for (Set<E> subset : powerSet) {
990       result.add(new HashSet<E>(subset));
991     }
992     return result;
993   }
994 
995   private static Object objectWithHashCode(final int hashCode) {
996     return new Object() {
997       @Override
998       public int hashCode() {
999         return hashCode;
1000       }
1001     };
1002   }
1003 
1004   private static void assertPowerSetHashCode(int expected, Set<?> elements) {
1005     assertEquals(expected, powerSet(elements).hashCode());
1006   }
1007 
1008   private static void assertPowerSetSize(int i, Object... elements) {
1009     assertEquals(i, powerSet(newHashSet(elements)).size());
1010   }
1011 
1012   private static void checkHashCode(Set<?> set) {
1013     assertEquals(Sets.newHashSet(set).hashCode(), set.hashCode());
1014   }
1015 
1016   public void testCombinations() {
1017     ImmutableList<Set<Integer>> sampleSets =
1018         ImmutableList.<Set<Integer>>of(
1019             ImmutableSet.<Integer>of(),
1020             ImmutableSet.of(1, 2),
1021             ImmutableSet.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
1022     for (Set<Integer> sampleSet : sampleSets) {
1023       for (int k = 0; k <= sampleSet.size(); k++) {
1024         final int size = k;
1025         Set<Set<Integer>> expected =
1026             Sets.filter(
1027                 Sets.powerSet(sampleSet),
1028                 new Predicate<Set<Integer>>() {
1029 
1030                   @Override
1031                   public boolean apply(Set<Integer> input) {
1032                     return input.size() == size;
1033                   }
1034                 });
1035         assertThat(Sets.combinations(sampleSet, k))
1036             .named("Sets.combinations(%s, %s)", sampleSet, k)
1037             .containsExactlyElementsIn(expected)
1038             .inOrder();
1039       }
1040     }
1041   }
1042 
1043   private static <E> Set<E> set(E... elements) {
1044     return ImmutableSet.copyOf(elements);
1045   }
1046 
1047   private static <E> List<E> list(E... elements) {
1048     return ImmutableList.copyOf(elements);
1049   }
1050 
1051   /**
1052    * Utility method to verify that the given LinkedHashSet is equal to and hashes identically to a
1053    * set constructed with the elements in the given collection. Also verifies that the ordering in
1054    * the set is the same as the ordering of the given contents.
1055    */
1056   private static <E> void verifyLinkedHashSetContents(
1057       LinkedHashSet<E> set, Collection<E> contents) {
1058     assertEquals(
1059         "LinkedHashSet should have preserved order for iteration",
1060         new ArrayList<E>(set),
1061         new ArrayList<E>(contents));
1062     verifySetContents(set, contents);
1063   }
1064 
1065   /**
1066    * Utility method to verify that the given SortedSet is equal to and hashes identically to a set
1067    * constructed with the elements in the given iterable. Also verifies that the comparator is the
1068    * same as the given comparator.
1069    */
1070   private static <E> void verifySortedSetContents(
1071       SortedSet<E> set, Iterable<E> iterable, @NullableDecl Comparator<E> comparator) {
1072     assertSame(comparator, set.comparator());
1073     verifySetContents(set, iterable);
1074   }
1075 
1076   /**
1077    * Utility method that verifies that the given set is equal to and hashes identically to a set
1078    * constructed with the elements in the given iterable.
1079    */
1080   private static <E> void verifySetContents(Set<E> set, Iterable<E> contents) {
1081     Set<E> expected = null;
1082     if (contents instanceof Set) {
1083       expected = (Set<E>) contents;
1084     } else {
1085       expected = new HashSet<E>();
1086       for (E element : contents) {
1087         expected.add(element);
1088       }
1089     }
1090     assertEquals(expected, set);
1091   }
1092 
1093   /** Simple base class to verify that we handle generics correctly. */
1094   static class Base implements Comparable<Base>, Serializable {
1095     private final String s;
1096 
1097     public Base(String s) {
1098       this.s = s;
1099     }
1100 
1101     @Override
1102     public int hashCode() { // delegate to 's'
1103       return s.hashCode();
1104     }
1105 
1106     @Override
1107     public boolean equals(Object other) {
1108       if (other == null) {
1109         return false;
1110       } else if (other instanceof Base) {
1111         return s.equals(((Base) other).s);
1112       } else {
1113         return false;
1114       }
1115     }
1116 
1117     @Override
1118     public int compareTo(Base o) {
1119       return s.compareTo(o.s);
1120     }
1121 
1122     private static final long serialVersionUID = 0;
1123   }
1124 
1125   /** Simple derived class to verify that we handle generics correctly. */
1126   static class Derived extends Base {
1127     public Derived(String s) {
1128       super(s);
1129     }
1130 
1131     private static final long serialVersionUID = 0;
1132   }
1133 
1134   @GwtIncompatible // NavigableSet
1135   public void testUnmodifiableNavigableSet() {
1136     TreeSet<Integer> mod = Sets.newTreeSet();
1137     mod.add(1);
1138     mod.add(2);
1139     mod.add(3);
1140 
1141     NavigableSet<Integer> unmod = unmodifiableNavigableSet(mod);
1142 
1143     /* Unmodifiable is a view. */
1144     mod.add(4);
1145     assertTrue(unmod.contains(4));
1146     assertTrue(unmod.descendingSet().contains(4));
1147 
1148     ensureNotDirectlyModifiable(unmod);
1149     ensureNotDirectlyModifiable(unmod.descendingSet());
1150     ensureNotDirectlyModifiable(unmod.headSet(2));
1151     ensureNotDirectlyModifiable(unmod.headSet(2, true));
1152     ensureNotDirectlyModifiable(unmod.tailSet(2));
1153     ensureNotDirectlyModifiable(unmod.tailSet(2, true));
1154     ensureNotDirectlyModifiable(unmod.subSet(1, 3));
1155     ensureNotDirectlyModifiable(unmod.subSet(1, true, 3, true));
1156 
1157     /* UnsupportedOperationException on indirect modifications. */
1158     NavigableSet<Integer> reverse = unmod.descendingSet();
1159     try {
1160       reverse.add(4);
1161       fail("UnsupportedOperationException expected");
1162     } catch (UnsupportedOperationException expected) {
1163     }
1164     try {
1165       reverse.addAll(Collections.singleton(4));
1166       fail("UnsupportedOperationException expected");
1167     } catch (UnsupportedOperationException expected) {
1168     }
1169     try {
1170       reverse.remove(4);
1171       fail("UnsupportedOperationException expected");
1172     } catch (UnsupportedOperationException expected) {
1173     }
1174   }
1175 
1176   void ensureNotDirectlyModifiable(SortedSet<Integer> unmod) {
1177     try {
1178       unmod.add(4);
1179       fail("UnsupportedOperationException expected");
1180     } catch (UnsupportedOperationException expected) {
1181     }
1182     try {
1183       unmod.remove(4);
1184       fail("UnsupportedOperationException expected");
1185     } catch (UnsupportedOperationException expected) {
1186     }
1187     try {
1188       unmod.addAll(Collections.singleton(4));
1189       fail("UnsupportedOperationException expected");
1190     } catch (UnsupportedOperationException expected) {
1191     }
1192     try {
1193       Iterator<Integer> iterator = unmod.iterator();
1194       iterator.next();
1195       iterator.remove();
1196       fail("UnsupportedOperationException expected");
1197     } catch (UnsupportedOperationException expected) {
1198     }
1199   }
1200 
1201   @GwtIncompatible // NavigableSet
1202   void ensureNotDirectlyModifiable(NavigableSet<Integer> unmod) {
1203     try {
1204       unmod.add(4);
1205       fail("UnsupportedOperationException expected");
1206     } catch (UnsupportedOperationException expected) {
1207     }
1208     try {
1209       unmod.remove(4);
1210       fail("UnsupportedOperationException expected");
1211     } catch (UnsupportedOperationException expected) {
1212     }
1213     try {
1214       unmod.addAll(Collections.singleton(4));
1215       fail("UnsupportedOperationException expected");
1216     } catch (UnsupportedOperationException expected) {
1217     }
1218     try {
1219       unmod.pollFirst();
1220       fail("UnsupportedOperationException expected");
1221     } catch (UnsupportedOperationException expected) {
1222     }
1223     try {
1224       unmod.pollLast();
1225       fail("UnsupportedOperationException expected");
1226     } catch (UnsupportedOperationException expected) {
1227     }
1228     try {
1229       Iterator<Integer> iterator = unmod.iterator();
1230       iterator.next();
1231       iterator.remove();
1232       fail("UnsupportedOperationException expected");
1233     } catch (UnsupportedOperationException expected) {
1234     }
1235     try {
1236       Iterator<Integer> iterator = unmod.descendingIterator();
1237       iterator.next();
1238       iterator.remove();
1239       fail("UnsupportedOperationException expected");
1240     } catch (UnsupportedOperationException expected) {
1241     }
1242   }
1243 
1244   @GwtIncompatible // NavigableSet
1245   public void testSubSet_boundedRange() {
1246     ImmutableSortedSet<Integer> set = ImmutableSortedSet.of(2, 4, 6, 8, 10);
1247     ImmutableSortedSet<Integer> empty = ImmutableSortedSet.of();
1248 
1249     assertEquals(set, Sets.subSet(set, Range.closed(0, 12)));
1250     assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.closed(0, 4)));
1251     assertEquals(ImmutableSortedSet.of(2, 4, 6), Sets.subSet(set, Range.closed(2, 6)));
1252     assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.closed(3, 7)));
1253     assertEquals(empty, Sets.subSet(set, Range.closed(20, 30)));
1254 
1255     assertEquals(set, Sets.subSet(set, Range.open(0, 12)));
1256     assertEquals(ImmutableSortedSet.of(2), Sets.subSet(set, Range.open(0, 4)));
1257     assertEquals(ImmutableSortedSet.of(4), Sets.subSet(set, Range.open(2, 6)));
1258     assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.open(3, 7)));
1259     assertEquals(empty, Sets.subSet(set, Range.open(20, 30)));
1260 
1261     assertEquals(set, Sets.subSet(set, Range.openClosed(0, 12)));
1262     assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.openClosed(0, 4)));
1263     assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.openClosed(2, 6)));
1264     assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.openClosed(3, 7)));
1265     assertEquals(empty, Sets.subSet(set, Range.openClosed(20, 30)));
1266 
1267     assertEquals(set, Sets.subSet(set, Range.closedOpen(0, 12)));
1268     assertEquals(ImmutableSortedSet.of(2), Sets.subSet(set, Range.closedOpen(0, 4)));
1269     assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.closedOpen(2, 6)));
1270     assertEquals(ImmutableSortedSet.of(4, 6), Sets.subSet(set, Range.closedOpen(3, 7)));
1271     assertEquals(empty, Sets.subSet(set, Range.closedOpen(20, 30)));
1272   }
1273 
1274   @GwtIncompatible // NavigableSet
1275   public void testSubSet_halfBoundedRange() {
1276     ImmutableSortedSet<Integer> set = ImmutableSortedSet.of(2, 4, 6, 8, 10);
1277     ImmutableSortedSet<Integer> empty = ImmutableSortedSet.of();
1278 
1279     assertEquals(set, Sets.subSet(set, Range.atLeast(0)));
1280     assertEquals(ImmutableSortedSet.of(4, 6, 8, 10), Sets.subSet(set, Range.atLeast(4)));
1281     assertEquals(ImmutableSortedSet.of(8, 10), Sets.subSet(set, Range.atLeast(7)));
1282     assertEquals(empty, Sets.subSet(set, Range.atLeast(20)));
1283 
1284     assertEquals(set, Sets.subSet(set, Range.greaterThan(0)));
1285     assertEquals(ImmutableSortedSet.of(6, 8, 10), Sets.subSet(set, Range.greaterThan(4)));
1286     assertEquals(ImmutableSortedSet.of(8, 10), Sets.subSet(set, Range.greaterThan(7)));
1287     assertEquals(empty, Sets.subSet(set, Range.greaterThan(20)));
1288 
1289     assertEquals(empty, Sets.subSet(set, Range.lessThan(0)));
1290     assertEquals(ImmutableSortedSet.of(2), Sets.subSet(set, Range.lessThan(4)));
1291     assertEquals(ImmutableSortedSet.of(2, 4, 6), Sets.subSet(set, Range.lessThan(7)));
1292     assertEquals(set, Sets.subSet(set, Range.lessThan(20)));
1293 
1294     assertEquals(empty, Sets.subSet(set, Range.atMost(0)));
1295     assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.atMost(4)));
1296     assertEquals(ImmutableSortedSet.of(2, 4, 6), Sets.subSet(set, Range.atMost(7)));
1297     assertEquals(set, Sets.subSet(set, Range.atMost(20)));
1298   }
1299 
1300   @GwtIncompatible // NavigableSet
1301   public void testSubSet_unboundedRange() {
1302     ImmutableSortedSet<Integer> set = ImmutableSortedSet.of(2, 4, 6, 8, 10);
1303 
1304     assertEquals(set, Sets.subSet(set, Range.<Integer>all()));
1305   }
1306 
1307   @GwtIncompatible // NavigableSet
1308   public void testSubSet_unnaturalOrdering() {
1309     ImmutableSortedSet<Integer> set =
1310         ImmutableSortedSet.<Integer>reverseOrder().add(2, 4, 6, 8, 10).build();
1311 
1312     try {
1313       Sets.subSet(set, Range.closed(4, 8));
1314       fail("IllegalArgumentException expected");
1315     } catch (IllegalArgumentException expected) {
1316     }
1317 
1318     // These results are all incorrect, but there's no way (short of iterating over the result)
1319     // to verify that with an arbitrary ordering or comparator.
1320     assertEquals(ImmutableSortedSet.of(2, 4), Sets.subSet(set, Range.atLeast(4)));
1321     assertEquals(ImmutableSortedSet.of(8, 10), Sets.subSet(set, Range.atMost(8)));
1322     assertEquals(ImmutableSortedSet.of(2, 4, 6, 8, 10), Sets.subSet(set, Range.<Integer>all()));
1323   }
1324 }
1325