@Test
  public void put() {
    int size = MORE_COLLISIONS.size();
    for (int i = 1; i <= size; i++) {
      Pool<Integer> unifiedSet =
          UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY, 1)
              .withAll(MORE_COLLISIONS.subList(0, i - 1));
      Integer newValue = MORE_COLLISIONS.get(i - 1);

      Assert.assertSame(newValue, unifiedSet.put(newValue));
      //noinspection UnnecessaryBoxing,CachedNumberConstructorCall,BoxingBoxedValue
      Assert.assertSame(newValue, unifiedSet.put(new Integer(newValue)));
    }

    // assert that all redundant puts into a each position of chain bucket return the original
    // element added
    Pool<Integer> set =
        UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY, 4)
            .with(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_4);
    for (int i = 0; i < set.size(); i++) {
      Integer value = COLLISIONS.get(i);
      Assert.assertSame(value, set.put(value));
    }

    // force rehashing at each step of putting a new colliding entry
    for (int i = 0; i < COLLISIONS.size(); i++) {
      Pool<Integer> pool =
          UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY, i)
              .withAll(COLLISIONS.subList(0, i));
      if (i == 2) {
        pool.put(Integer.valueOf(1));
      }
      if (i == 4) {
        pool.put(Integer.valueOf(1));
        pool.put(Integer.valueOf(2));
      }
      Integer value = COLLISIONS.get(i);
      Assert.assertSame(value, pool.put(value));
    }

    // cover one case not covered in the above: a bucket with only one entry and a low capacity
    // forcing a rehash
    // set up a chained bucket
    Pool<Integer> pool =
        UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY, 2)
            .with(COLLISION_1, COLLISION_2);
    // clear the bucket to one element
    pool.removeFromPool(COLLISION_2);
    // increase the occupied count to the threshold
    pool.put(Integer.valueOf(1));
    pool.put(Integer.valueOf(2));

    // put the colliding value back and force the rehash
    Assert.assertSame(COLLISION_2, pool.put(COLLISION_2));

    // put chained items into a pool without causing a rehash
    Pool<Integer> olympicPool = UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY);
    Assert.assertSame(COLLISION_1, olympicPool.put(COLLISION_1));
    Assert.assertSame(COLLISION_2, olympicPool.put(COLLISION_2));
  }
  @Override
  @Test
  public void add() {
    super.add();

    // force rehashing at each step of adding a new colliding entry
    for (int i = 0; i < COLLISIONS.size(); i++) {
      UnifiedSetWithHashingStrategy<Integer> unifiedSet =
          UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY, i, 0.75f)
              .withAll(COLLISIONS.subList(0, i));
      if (i == 2) {
        unifiedSet.add(Integer.valueOf(1));
      }
      if (i == 4) {
        unifiedSet.add(Integer.valueOf(1));
        unifiedSet.add(Integer.valueOf(2));
      }
      Integer value = COLLISIONS.get(i);
      Assert.assertTrue(unifiedSet.add(value));
    }

    // Rehashing Case A: a bucket with only one entry and a low capacity forcing a rehash, where the
    // trigging element goes in the bucket
    // set up a chained bucket
    UnifiedSetWithHashingStrategy<Integer> caseA =
        UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY, 2)
            .with(COLLISION_1, COLLISION_2);
    // clear the bucket to one element
    caseA.remove(COLLISION_2);
    // increase the occupied count to the threshold
    caseA.add(Integer.valueOf(1));
    caseA.add(Integer.valueOf(2));

    // add the colliding value back and force the rehash
    Assert.assertTrue(caseA.add(COLLISION_2));

    // Rehashing Case B: a bucket with only one entry and a low capacity forcing a rehash, where the
    // triggering element is not in the chain
    // set up a chained bucket
    UnifiedSetWithHashingStrategy<Integer> caseB =
        UnifiedSetWithHashingStrategy.newSet(INTEGER_HASHING_STRATEGY, 2)
            .with(COLLISION_1, COLLISION_2);
    // clear the bucket to one element
    caseB.remove(COLLISION_2);
    // increase the occupied count to the threshold
    caseB.add(Integer.valueOf(1));
    caseB.add(Integer.valueOf(2));

    // add a new value and force the rehash
    Assert.assertTrue(caseB.add(3));
  }