@Test
  public void rejectWith_value() {
    ImmutableMap<String, Integer> map = this.newMapWithKeysValues("1", 1, "2", 2, "3", 3, "4", 4);

    switch (map.size()) {
      case 1:
        Verify.assertEmpty(
            map.rejectWith(Predicates2.<Integer>lessThan(), 2, UnifiedSet.<Integer>newSet()));
        break;
      case 2:
        Verify.assertContainsAll(
            map.rejectWith(Predicates2.<Integer>lessThan(), 2, UnifiedSet.<Integer>newSet()), 2);
        break;
      case 3:
        Verify.assertContainsAll(
            map.rejectWith(Predicates2.<Integer>lessThan(), 2, UnifiedSet.<Integer>newSet()), 2, 3);
        break;
      case 4:
        Verify.assertContainsAll(
            map.rejectWith(Predicates2.<Integer>lessThan(), 2, UnifiedSet.<Integer>newSet()),
            2,
            3,
            4);
        break;
      default:
        Verify.assertEmpty(map);
        break;
    }
  }
  @Override
  @Test
  public void forEachWithIndex() {
    super.forEachWithIndex();

    final UnifiedSet<String> set = UnifiedSet.newSet();

    // map with a chain and no empty slots
    MutableMap<Integer, Integer> map = this.mapWithCollisionsOfSize(2);
    map.forEachWithIndex(
        new ObjectIntProcedure<Integer>() {
          public void value(Integer each, int index) {
            set.add(index + ":" + each.toString());
          }
        });
    Assert.assertEquals(UnifiedSet.newSetWith("0:0", "1:17"), set);

    set.clear();

    // map with a chain and empty slots
    MutableMap<Integer, Integer> map2 = this.mapWithCollisionsOfSize(5);
    map2.forEachWithIndex(
        new ObjectIntProcedure<Integer>() {
          public void value(Integer each, int index) {
            set.add(index + ":" + each.toString());
          }
        });
    Assert.assertEquals(UnifiedSet.newSetWith("0:0", "1:17", "2:34", "3:51", "4:68"), set);
  }
 @Test
 public void forEachKeyMultiValue() {
   MutableSet<Pair<Integer, Iterable<String>>> collection = UnifiedSet.newSet();
   Multimap<Integer, String> multimap =
       this.newMultimapWithKeysValues(2, "2", 2, "1", 3, "3", 3, "3");
   multimap.forEachKeyMultiValues((key, values) -> collection.add(Tuples.pair(key, values)));
   Assert.assertEquals(
       UnifiedSet.newSetWith(
           Tuples.pair(2, this.createCollection("2", "1")),
           Tuples.pair(3, this.createCollection("3", "3"))),
       collection);
 }
  @Test
  public void zipWithIndex() {
    LazyIterable<Pair<Integer, Integer>> pairs = this.lazyIterable.zipWithIndex();

    Assert.assertEquals(
        this.lazyIterable.toSet(), pairs.collect(Functions.<Integer>firstOfPair()).toSet());
    Assert.assertEquals(
        Interval.zeroTo(this.lazyIterable.size() - 1).toSet(),
        pairs.collect(Functions.<Integer>secondOfPair(), UnifiedSet.<Integer>newSet()));

    Assert.assertEquals(
        this.lazyIterable.zipWithIndex().toSet(),
        this.lazyIterable.zipWithIndex(UnifiedSet.<Pair<Integer, Integer>>newSet()));
  }
  @Test
  public void testForEachUsingSet() {
    // Tests the default batch size calculations
    IntegerSum sum = new IntegerSum(0);
    MutableSet<Integer> set = Interval.toSet(1, 10000);
    ParallelIterate.forEach(set, new SumProcedure(sum), new SumCombiner(sum));
    Assert.assertEquals(50005000, sum.getSum());

    // Testing batch size 1
    IntegerSum sum2 = new IntegerSum(0);
    UnifiedSet<Integer> set2 = UnifiedSet.newSet(Interval.oneTo(100));
    ParallelIterate.forEach(
        set2, new SumProcedure(sum2), new SumCombiner(sum2), 1, set2.getBatchCount(set2.size()));
    Assert.assertEquals(5050, sum2.getSum());

    // Testing an uneven batch size
    IntegerSum sum3 = new IntegerSum(0);
    UnifiedSet<Integer> set3 = UnifiedSet.newSet(Interval.oneTo(100));
    ParallelIterate.forEach(
        set3, new SumProcedure(sum3), new SumCombiner(sum3), 1, set3.getBatchCount(13));
    Assert.assertEquals(5050, sum3.getSum());

    // Testing divideByZero exception by passing 1 as batchSize
    IntegerSum sum4 = new IntegerSum(0);
    UnifiedSet<Integer> set4 = UnifiedSet.newSet(Interval.oneTo(100));
    ParallelIterate.forEach(set4, new SumProcedure(sum4), new SumCombiner(sum4), 1);
    Assert.assertEquals(5050, sum4.getSum());
  }
  @Test
  public void entrySet_equals() {
    MutableMap<Integer, String> map =
        this.newMapWithKeysValues(1, "One", 2, "Two", 3, "Three", 4, "Four");
    Verify.assertNotEquals(UnifiedSet.newSetWith(ImmutableEntry.of(5, "Five")), map.entrySet());

    UnifiedSet<ImmutableEntry<Integer, String>> expected =
        UnifiedSet.newSetWith(
            ImmutableEntry.of(1, "One"),
            ImmutableEntry.of(2, "Two"),
            ImmutableEntry.of(3, "Three"),
            ImmutableEntry.of(4, "Four"));
    Assert.assertEquals(expected, map.entrySet());
  }
  @Test
  public void zip() {
    List<Object> nulls = Collections.nCopies(this.lazyIterable.size(), null);
    List<Object> nullsPlusOne = Collections.nCopies(this.lazyIterable.size() + 1, null);
    List<Object> nullsMinusOne = Collections.nCopies(this.lazyIterable.size() - 1, null);

    LazyIterable<Pair<Integer, Object>> pairs = this.lazyIterable.zip(nulls);
    Assert.assertEquals(
        this.lazyIterable.toSet(), pairs.collect(Functions.<Integer>firstOfPair()).toSet());
    Assert.assertEquals(nulls, pairs.collect(Functions.<Object>secondOfPair(), Lists.mutable.of()));

    LazyIterable<Pair<Integer, Object>> pairsPlusOne = this.lazyIterable.zip(nullsPlusOne);
    Assert.assertEquals(
        this.lazyIterable.toSet(), pairsPlusOne.collect(Functions.<Integer>firstOfPair()).toSet());
    Assert.assertEquals(
        nulls, pairsPlusOne.collect(Functions.<Object>secondOfPair(), Lists.mutable.of()));

    LazyIterable<Pair<Integer, Object>> pairsMinusOne = this.lazyIterable.zip(nullsMinusOne);
    Assert.assertEquals(this.lazyIterable.size() - 1, pairsMinusOne.size());
    Assert.assertTrue(
        this.lazyIterable.containsAllIterable(
            pairsMinusOne.collect(Functions.<Integer>firstOfPair())));

    Assert.assertEquals(
        this.lazyIterable.zip(nulls).toSet(),
        this.lazyIterable.zip(nulls, UnifiedSet.<Pair<Integer, Object>>newSet()));
  }
 @Test
 public void keySetEqualsAndHashCode() {
   MutableMapIterable<String, Integer> map =
       this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3, null, null);
   Verify.assertEqualsAndHashCode(
       UnifiedSet.newSetWith("One", "Two", "Three", null), map.keySet());
 }
  @Test
  public void zip() {
    MutableMap<String, String> map = this.classUnderTest();

    List<Object> nulls = Collections.nCopies(map.size(), null);
    List<Object> nullsPlusOne = Collections.nCopies(map.size() + 1, null);

    RichIterable<Pair<String, Object>> pairs = map.zip(nulls);
    Assert.assertEquals(
        map.toSet(), pairs.collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet());
    Assert.assertEquals(
        nulls, pairs.collect((Function<Pair<?, Object>, Object>) Pair::getTwo, Lists.mutable.of()));

    RichIterable<Pair<String, Object>> pairsPlusOne = map.zip(nullsPlusOne);
    Assert.assertEquals(
        map.toSet(),
        pairsPlusOne.collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet());
    Assert.assertEquals(
        nulls,
        pairsPlusOne.collect((Function<Pair<?, Object>, Object>) Pair::getTwo, Lists.mutable.of()));

    if (map.notEmpty()) {
      List<Object> nullsMinusOne = Collections.nCopies(map.size() - 1, null);
      RichIterable<Pair<String, Object>> pairsMinusOne = map.zip(nullsMinusOne);
      Assert.assertEquals(map.size() - 1, pairsMinusOne.size());
      Assert.assertTrue(
          map.values()
              .containsAll(
                  pairsMinusOne.collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet()));
    }

    Assert.assertEquals(
        map.zip(nulls).toSet(), map.zip(nulls, UnifiedSet.<Pair<String, Object>>newSet()));
  }
  @Test
  public void collect_value() {
    ImmutableMap<String, Integer> map = this.newMapWithKeysValues("1", 1, "2", 2, "3", 3, "4", 4);
    MutableSet<String> collect = map.collect(Functions.getToString()).toSet();
    UnifiedSet<String> collectToTarget = map.collect(String::valueOf, UnifiedSet.<String>newSet());

    switch (map.size()) {
      case 1:
        Verify.assertContainsAll(collect, "1");
        Verify.assertContainsAll(collectToTarget, "1");
        break;
      case 2:
        Verify.assertContainsAll(collect, "1", "2");
        Verify.assertContainsAll(collectToTarget, "1", "2");
        break;
      case 3:
        Verify.assertContainsAll(collect, "1", "2", "3");
        Verify.assertContainsAll(collectToTarget, "1", "2", "3");
        break;
      case 4:
        Verify.assertContainsAll(collect, "1", "2", "3", "4");
        Verify.assertContainsAll(collectToTarget, "1", "2", "3", "4");
        break;
      default:
        Verify.assertEmpty(collect);
        break;
    }
  }
  @Test
  public void collectIf() {
    MutableMap<String, Integer> map = this.newMapWithKeysValues("1", 1, "2", 2, "3", 3);

    MutableSet<String> collect = map.collectIf(Integer.class::isInstance, String::valueOf).toSet();
    UnifiedSet<String> collectToTarget =
        map.collectIf(Integer.class::isInstance, String::valueOf, UnifiedSet.<String>newSet());

    switch (map.size()) {
      case 1:
        Verify.assertContainsAll(collect, "1");
        Verify.assertContainsAll(collectToTarget, "1");
        break;
      case 2:
        Verify.assertContainsAll(collect, "1", "2");
        Verify.assertContainsAll(collectToTarget, "1", "2");
        break;
      case 3:
        Verify.assertContainsAll(collect, "1", "2", "3");
        Verify.assertContainsAll(collectToTarget, "1", "2", "3");
        break;
      default:
        Verify.assertEmpty(collect);
        break;
    }
  }
  @Test
  public void zip() {
    ImmutableMap<String, String> map =
        this.newMapWithKeysValues("1", "One", "2", "Two", "3", "Three", "4", "Four");

    List<Object> nulls = Collections.nCopies(map.size(), null);
    List<Object> nullsPlusOne = Collections.nCopies(map.size() + 1, null);

    RichIterable<Pair<String, Object>> pairs = map.zip(nulls);
    Assert.assertEquals(
        map.toSet(), pairs.collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet());
    Assert.assertEquals(
        nulls, pairs.collect((Function<Pair<?, Object>, Object>) Pair::getTwo, Lists.mutable.of()));

    RichIterable<Pair<String, Object>> pairsPlusOne = map.zip(nullsPlusOne);
    Assert.assertEquals(
        map.toSet(),
        pairsPlusOne.collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet());
    Assert.assertEquals(
        nulls,
        pairsPlusOne.collect((Function<Pair<?, Object>, Object>) Pair::getTwo, Lists.mutable.of()));

    if (map.notEmpty()) {
      List<Object> nullsMinusOne = Collections.nCopies(map.size() - 1, null);
      RichIterable<Pair<String, Object>> pairsMinusOne = map.zip(nullsMinusOne);
      Assert.assertEquals(map.size() - 1, pairsMinusOne.size());
    }

    Assert.assertEquals(
        map.zip(nulls).toSet(), map.zip(nulls, UnifiedSet.<Pair<String, Object>>newSet()));
  }
  @Test
  public void keySet_hashCode() {
    // a map with a null key
    MutableMap<Integer, Integer> map1 = this.newMapWithKeyValue(null, 0);
    UnifiedSet<Object> set = UnifiedSet.newSet();
    set.add(null);
    Verify.assertEqualsAndHashCode(set, map1.keySet());

    // a map with a chain containing empty slots
    MutableMap<Integer, Integer> map2 = this.mapWithCollisionsOfSize(5);
    Verify.assertEqualsAndHashCode(UnifiedSet.newSetWith(0, 17, 34, 51, 68), map2.keySet());

    // a map with a chain containing empty slots and a null key
    MutableMap<Integer, Integer> map3 = this.mapWithCollisionsOfSize(5);
    map3.put(null, 42);
    Verify.assertEqualsAndHashCode(UnifiedSet.newSetWith(0, 17, 34, 51, 68, null), map3.keySet());
  }
 @Override
 @Test
 public void testClone() {
   Verify.assertShallowClone(this.set);
   MutableSet<String> cloneSet = this.set.clone();
   Assert.assertNotSame(cloneSet, this.set);
   Verify.assertEqualsAndHashCode(UnifiedSet.newSetWith("1", "2", "3", "4"), cloneSet);
 }
  @Test
  public void flatCollect() {
    LazyIterable<Integer> collection = this.newWith(1, 2, 3, 4);
    Function<Integer, MutableList<String>> function =
        new Function<Integer, MutableList<String>>() {
          public MutableList<String> valueOf(Integer object) {
            return FastList.newListWith(String.valueOf(object));
          }
        };

    Verify.assertListsEqual(
        FastList.newListWith("1", "2", "3", "4"), collection.flatCollect(function).toSortedList());

    Verify.assertSetsEqual(
        UnifiedSet.newSetWith("1", "2", "3", "4"),
        collection.flatCollect(function, UnifiedSet.<String>newSet()));
  }
  @Override
  @Test
  public void forEachKey() {
    super.forEachKey();

    final UnifiedSet<String> set = UnifiedSet.newSet(5);

    // map with a chain and empty slots
    MutableMap<Integer, Integer> map = this.mapWithCollisionsOfSize(5);
    map.forEachKey(
        new Procedure<Integer>() {
          public void value(Integer each) {
            set.add(each.toString());
          }
        });
    Assert.assertEquals(UnifiedSet.newSetWith("0", "17", "34", "51", "68"), set);
  }
  @Override
  @Test
  public void zipWithIndex() {
    ImmutableBag<String> immutableBag = this.newBag();
    ImmutableSet<Pair<String, Integer>> pairs = immutableBag.zipWithIndex();

    Assert.assertEquals(
        UnifiedSet.<String>newSet(),
        pairs.collect((Function<Pair<String, ?>, String>) Pair::getOne));
    Assert.assertEquals(
        UnifiedSet.<Integer>newSet(),
        pairs.collect((Function<Pair<?, Integer>, Integer>) Pair::getTwo));

    Assert.assertEquals(
        immutableBag.zipWithIndex(),
        immutableBag.zipWithIndex(UnifiedSet.<Pair<String, Integer>>newSet()));
  }
 @Test
 public void toSet() {
   MutableSet<String> expectedSet =
       this.numKeys() == 0
           ? UnifiedSet.<String>newSet()
           : Interval.oneTo(this.numKeys()).collect(String::valueOf).toSet();
   Assert.assertEquals(expectedSet, this.newBag().toSet());
 }
  @Test
  public void zipWithIndex() {
    MutableMap<String, String> map = this.classUnderTest();

    RichIterable<Pair<String, Integer>> pairs = map.zipWithIndex();

    Assert.assertEquals(
        map.toSet(), pairs.collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet());
    if (map.notEmpty()) {
      Assert.assertEquals(
          Interval.zeroTo(map.size() - 1).toSet(),
          pairs.collect(
              (Function<Pair<?, Integer>, Integer>) Pair::getTwo, UnifiedSet.<Integer>newSet()));
    }

    Assert.assertEquals(
        map.zipWithIndex().toSet(), map.zipWithIndex(UnifiedSet.<Pair<String, Integer>>newSet()));
  }
  @Test
  public void select_value() {
    MutableMap<String, Integer> map = this.newMapWithKeysValues("1", 1, "2", 2, "3", 3);
    ImmutableSet<Integer> expected = this.expectSelect(map.size());

    Assert.assertEquals(expected, map.select(IntegerPredicates.isEven()).toSet());
    Assert.assertEquals(
        expected, map.select(IntegerPredicates.isEven(), UnifiedSet.<Integer>newSet()));
  }
 @Override
 @Test
 public void equalsAndHashCode() {
   super.equalsAndHashCode();
   MutableSet<String> quadrupletonSet = Sets.fixedSize.of("1", "2", "3", "4");
   MutableSet<String> set = UnifiedSet.newSetWith("1", "2", "3", "4");
   Verify.assertEqualsAndHashCode(quadrupletonSet, set);
   Verify.assertPostSerializedEqualsAndHashCode(quadrupletonSet);
 }
  @Test
  public void zipWithIndex() {
    ImmutableMap<String, String> map =
        this.newMapWithKeysValues("1", "One", "2", "Two", "3", "Three", "4", "Four");

    RichIterable<Pair<String, Integer>> pairs = map.zipWithIndex();

    Assert.assertEquals(
        map.toSet(), pairs.collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet());
    if (map.notEmpty()) {
      Assert.assertEquals(
          Interval.zeroTo(map.size() - 1).toSet(),
          pairs.collect(
              (Function<Pair<?, Integer>, Integer>) Pair::getTwo, UnifiedSet.<Integer>newSet()));
    }

    Assert.assertEquals(
        map.zipWithIndex().toSet(), map.zipWithIndex(UnifiedSet.<Pair<String, Integer>>newSet()));
  }
  @Test
  public void newWithoutAll() {
    ImmutableBag<String> bag = this.newBag();
    ImmutableBag<String> withoutAll = bag.newWithoutAll(UnifiedSet.newSet(this.newBag()));
    Assert.assertEquals(Bags.immutable.of(), withoutAll);

    ImmutableBag<String> newBag =
        bag.newWithAll(Lists.fixedSize.of("0", "0", "0")).newWithoutAll(Lists.fixedSize.of("0"));

    Assert.assertEquals(0, newBag.occurrencesOf("0"));
  }
 @Test
 public void entrySetEqualsAndHashCode() {
   MutableMapIterable<String, Integer> map =
       this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
   Verify.assertEqualsAndHashCode(
       UnifiedSet.newSetWith(
           ImmutableEntry.of("One", 1),
           ImmutableEntry.of("Two", 2),
           ImmutableEntry.of("Three", 3)),
       map.entrySet());
 }
  @Test
  public void reject_value() {
    ImmutableMap<String, Integer> map = this.newMapWithKeysValues("1", 1, "2", 2, "3", 3, "4", 4);

    MutableSet<Integer> rejected = map.reject(IntegerPredicates.isEven()).toSet();
    UnifiedSet<Integer> rejectedIntoTarget =
        map.reject(IntegerPredicates.isEven(), UnifiedSet.<Integer>newSet());

    ImmutableSet<Integer> expected = this.expectReject(map.size());
    Assert.assertEquals(expected, rejected);
    Assert.assertEquals(expected, rejectedIntoTarget);
  }
  @Test
  public void getLast() {
    ImmutableMap<String, String> map =
        this.newMapWithKeysValues("1", "One", "2", "Two", "3", "Three", "4", "Four");

    if (map.isEmpty()) {
      String value = map.getLast();
      Assert.assertNull(value);
    } else {
      String value = map.getLast();
      Assert.assertNotNull(value);
      Verify.assertContains(value, UnifiedSet.newSetWith("One", "Two", "Three", "Four"));
    }
  }
  @Test
  public void zipWithIndex() {
    ImmutableBag<String> immutableBag = this.newBag();
    ImmutableSet<Pair<String, Integer>> pairs = immutableBag.zipWithIndex();

    Assert.assertEquals(
        immutableBag,
        pairs.collect((Function<Pair<String, ?>, String>) Pair::getOne, HashBag.<String>newBag()));
    Assert.assertEquals(
        Interval.zeroTo(immutableBag.size() - 1).toSet(),
        pairs.collect((Function<Pair<?, Integer>, Integer>) Pair::getTwo));

    Assert.assertEquals(
        immutableBag.zipWithIndex(),
        immutableBag.zipWithIndex(UnifiedSet.<Pair<String, Integer>>newSet()));
  }
  @Override
  @Test
  public void forEachWith() {
    super.forEachWith();

    for (int i = 1; i < COLLISIONS.size(); i++) {
      MutableMap<Integer, Integer> map = this.mapWithCollisionsOfSize(i);
      final Object sentinal = new Object();
      final UnifiedSet<Integer> result = UnifiedSet.newSet();
      map.forEachWith(
          new Procedure2<Integer, Object>() {
            public void value(Integer argument1, Object argument2) {
              Assert.assertSame(sentinal, argument2);
              result.add(argument1);
            }
          },
          sentinal);
      Assert.assertEquals(map.keySet(), result);
    }
  }
 public <V> MutableSet<V> collect(BooleanToObjectFunction<? extends V> function) {
   UnifiedSet<V> target = UnifiedSet.newSet(this.size());
   switch (this.state) {
     case 0:
       return target;
     case 1:
       return target.with(function.valueOf(false));
     case 2:
       return target.with(function.valueOf(true));
     case 3:
       target.add(function.valueOf(false));
       target.add(function.valueOf(true));
       return target;
     default:
       throw new AssertionError("Invalid state");
   }
 }
 public MutableSet<T> toSet() {
   return UnifiedSet.newSet(this);
 }