/**
   * Check that the set is consistent, i.e all allocated slots are reachable by get(), and all
   * not-allocated contains nulls if Generic
   *
   * @param set
   */
  @After
  public void checkConsistency() {
    if (this.set != null) {
      int occupied = 0;

      final int mask = getKeys(this.set).length - 1;

      for (int i = 0; i < getKeys(this.set).length; i++) {
        if (!is_allocated(i, Intrinsics.<KType[]>cast(getKeys(this.set)))) {
          // if not allocated, generic version if patched to null for GC sake
          /*! #if ($TemplateOptions.KTypeGeneric) !*/
          TestUtils.assertEquals2(this.keyE, getKeys(this.set)[i]);
          /*! #end !*/
        } else {
          // try to reach the key by contains()
          Assert.assertTrue(this.set.contains(Intrinsics.<KType>cast(getKeys(this.set)[i])));

          occupied++;
        }
      }

      if (isAllocatedDefaultKey(this.set)) {

        // try to reach the key by contains()
        Assert.assertTrue(this.set.contains(this.keyE));

        occupied++;
      }

      Assert.assertEquals(occupied, this.set.size());
    }
  }
  @Test
  public void testIterable2() {
    addFromArray(this.set, this.keyE, this.key1, this.key2, this.key2, this.key3, this.key4);
    this.set.remove(this.k2);
    Assert.assertEquals(4, this.set.size());

    int counted = 0;
    for (final KTypeCursor<KType> cursor : this.set) {
      if (cursor.index == getKeys(this.set).length) {

        Assert.assertTrue(this.isAllocatedDefaultKey(this.set));
        TestUtils.assertEquals2(this.keyE, cursor.value);
        counted++;
        continue;
      }

      Assert.assertTrue(this.set.contains(cursor.value));
      TestUtils.assertEquals2(cursor.value, this.getKeys(this.set)[cursor.index]);
      counted++;
    }
    Assert.assertEquals(counted, this.set.size());

    this.set.clear();
    Assert.assertFalse(this.set.iterator().hasNext());
  }
  /**
   * Run some random insertions/ deletions and compare the results against <code>java.util.HashSet
   * </code>.
   */
  @Test
  public void testAgainstHashMap() {
    final java.util.Random rnd = new Random(0xBADCAFE);
    final java.util.HashSet<KType> other = new java.util.HashSet<KType>();

    for (int size = 1000; size < 20000; size += 4000) {
      other.clear();
      this.set.clear();

      for (int round = 0; round < size * 20; round++) {
        final KType key = cast(rnd.nextInt(size));

        if (rnd.nextBoolean()) {
          other.add(key);
          this.set.add(key);

          Assert.assertTrue(this.set.contains(key));
        } else {
          Assert.assertTrue(
              "size= " + size + ", round = " + round, other.remove(key) == this.set.remove(key));
        }

        Assert.assertEquals(other.size(), this.set.size());
      }
    }
  }
 @Test
 public void testNullKey() {
   this.set.add((KType) null);
   Assert.assertEquals(1, this.set.size());
   Assert.assertTrue(this.set.contains(null));
   Assert.assertTrue(this.set.remove(null));
   Assert.assertEquals(0, this.set.size());
   Assert.assertFalse(this.set.contains(null));
 }
  /*! #if ($TemplateOptions.KTypeGeneric) !*/
  @SuppressWarnings("unchecked")
  @Test
  public void testHashCodeWithNulls() {
    final KTypeSet<KType> l1 = getFrom(this.k1, null, this.k3);
    final KTypeSet<KType> l2 = getFrom(this.k1, null);
    l2.add(this.k3);

    Assert.assertEquals(l1.hashCode(), l2.hashCode());
    Assert.assertEquals(l1, l2);
  }
  @Test
  public void testClear() {
    addFromArray(this.set, asArray(1, 2, 3));
    this.set.clear();
    checkConsistency();
    Assert.assertEquals(0, this.set.size());

    addFromArray(this.set, asArray(0, 2, 8));
    this.set.clear();
    checkConsistency();
    Assert.assertEquals(0, this.set.size());
  }
  @Test
  public void testRemove() {
    Assert.assertFalse(this.set.remove(this.k2));
    Assert.assertFalse(this.set.remove(this.keyE));

    addFromArray(this.set, this.key0, this.key1, this.key2, this.key3, this.key4);

    Assert.assertTrue(this.set.remove(this.k2));
    Assert.assertFalse(this.set.remove(this.k2));
    Assert.assertEquals(4, this.set.size());
    TestUtils.assertSortedListEquals(this.set.toArray(), 0, 1, 3, 4);
  }
  @Test
  public void testAddAll() {
    final KTypeSet<KType> set2 = createNewSetInstance();
    addFromArray(set2, asArray(1, 2));
    addFromArray(this.set, asArray(0, 1));

    Assert.assertEquals(1, this.set.addAll(set2));
    Assert.assertEquals(0, this.set.addAll(set2));

    Assert.assertEquals(3, this.set.size());
    TestUtils.assertSortedListEquals(this.set.toArray(), 0, 1, 2);
  }
  @Test
  public void testRemoveAllFromLookupContainer() {
    addFromArray(this.set, asArray(0, 1, 2, 3, 4));

    // test against concrete HashSet
    final KTypeHashSet<KType> set2 = new KTypeHashSet<KType>();
    set2.add(asArray(1, 3, 5));

    Assert.assertEquals(2, this.set.removeAll(set2));

    Assert.assertEquals(3, this.set.size());
    TestUtils.assertSortedListEquals(this.set.toArray(), 0, 2, 4);
  }
  @Test
  public void testPooledIteratorFullIteratorLoop() {
    // A) for-each loop interrupted

    // must accommodate even the smallest primitive type
    // so that the iteration do not break before it should...
    final int TEST_SIZE = 126;
    final long TEST_ROUNDS = 5000;

    final KTypeSet<KType> testContainer = createSetWithOrderedData(TEST_SIZE);

    final long checksum =
        testContainer.forEach(
                new KTypeProcedure<KType>() {

                  long count;

                  @Override
                  public void apply(final KType value) {
                    this.count += castType(value);
                  }
                })
            .count;

    long testValue = 0;
    final int startingPoolSize = getEntryPoolSize(testContainer);

    for (int round = 0; round < TEST_ROUNDS; round++) {
      // Classical iterator loop, with manually allocated Iterator
      final int initialPoolSize = getEntryPoolSize(testContainer);

      final AbstractIterator<KTypeCursor<KType>> loopIterator =
          (AbstractIterator<KTypeCursor<KType>>) testContainer.iterator();

      Assert.assertEquals(initialPoolSize - 1, getEntryPoolSize(testContainer));

      testValue = 0;
      while (loopIterator.hasNext()) {
        testValue += castType(loopIterator.next().value);
      } // end IteratorLoop

      // iterator is returned automatically to its pool, by normal iteration termination
      Assert.assertEquals(initialPoolSize, getEntryPoolSize(testContainer));

      // checksum
      Assert.assertEquals(checksum, testValue);
    } // end for rounds

    // pool initial size is untouched anyway
    Assert.assertEquals(startingPoolSize, getEntryPoolSize(testContainer));
  }
  @Repeat(iterations = 10)
  @Test
  public void testPreallocatedSize() {
    final Random randomVK = RandomizedTest.getRandom();
    // Test that the container do not resize if less that the initial size

    // 1) Choose a random number of elements
    /*! #if ($TemplateOptions.isKType("GENERIC", "INT", "LONG", "FLOAT", "DOUBLE")) !*/
    final int PREALLOCATED_SIZE = randomVK.nextInt(10000);
    /*!
    #elseif ($TemplateOptions.isKType("SHORT", "CHAR"))
     int PREALLOCATED_SIZE = randomVK.nextInt(1500);
    #else
      int PREALLOCATED_SIZE = randomVK.nextInt(126);
    #end !*/

    final KTypeSet<KType> newSet =
        createNewSetInstance(PREALLOCATED_SIZE, HashContainers.DEFAULT_LOAD_FACTOR);

    // computed real capacity
    final int realCapacity = newSet.capacity();

    // 3) Add PREALLOCATED_SIZE different values. At the end, size() must be == realCapacity,
    // and internal buffer/allocated must not have changed of size
    final int contructorBufferSize = getKeys(newSet).length;

    Assert.assertEquals(contructorBufferSize, getKeys(newSet).length);

    for (int i = 0; i < 1.5 * realCapacity; i++) {

      newSet.add(cast(i));

      // internal size has not changed until realCapacity
      if (newSet.size() <= realCapacity) {

        Assert.assertEquals(contructorBufferSize, getKeys(newSet).length);
      }

      if (contructorBufferSize < getKeys(newSet).length) {
        // The container as just reallocated, its actual size must be not too far from the previous
        // capacity:
        Assert.assertTrue(
            "Container as reallocated at size = "
                + newSet.size()
                + " with previous capacity = "
                + realCapacity,
            (newSet.size() - realCapacity) <= 3);
        break;
      }
    }
  }
  @Test
  public void testPooledIteratorBrokenIteratorLoop() {
    // A) for-each loop interrupted

    // must accommodate even the smallest primitive type
    // so that the iteration do not break before it should...
    final int TEST_SIZE = 126;
    final long TEST_ROUNDS = 5000;

    final KTypeSet<KType> testContainer = createSetWithOrderedData(TEST_SIZE);
    final int startingPoolSize = getEntryPoolSize(testContainer);

    int count = 0;
    for (int round = 0; round < TEST_ROUNDS; round++) {
      // Classical iterator loop, with manually allocated Iterator
      final long initialPoolSize = getEntryPoolSize(testContainer);

      final AbstractIterator<KTypeCursor<KType>> loopIterator =
          (AbstractIterator<KTypeCursor<KType>>) testContainer.iterator();

      Assert.assertEquals(initialPoolSize - 1, getEntryPoolSize(testContainer));

      count = 0;
      int guard = 0;
      while (loopIterator.hasNext()) {
        guard += castType(loopIterator.next().value);

        // brutally interrupt in the middle
        if (count > TEST_SIZE / 2) {
          break;
        }
        count++;
      } // end IteratorLoop

      // iterator is NOT returned to its pool, due to the break.
      Assert.assertEquals(initialPoolSize - 1, getEntryPoolSize(testContainer));

      // manual return to the pool
      loopIterator.release();

      // now the pool is restored
      Assert.assertEquals(initialPoolSize, getEntryPoolSize(testContainer));
    } // end for rounds

    // pool initial size is untouched anyway
    Assert.assertEquals(startingPoolSize, getEntryPoolSize(testContainer));
  }
  @Test
  public void testForEachProcedure() {
    // Test that the container do not resize if less that the initial size

    // 1) Choose a map to build
    /*! #if ($TemplateOptions.isKType("GENERIC", "int", "long", "float", "double")) !*/
    final int NB_ELEMENTS = 2000;
    /*!
    #elseif ($TemplateOptions.isKType("short", "char"))
     int NB_ELEMENTS = 1000;
    #else
      int NB_ELEMENTS = 126;
    #end !*/

    final KTypeSet<KType> newSet = createNewSetInstance();

    newSet.add(this.keyE);

    // add a increasing number of key
    for (int i = 0; i < NB_ELEMENTS; i++) {

      final int KVpair = i;

      newSet.add(cast(KVpair));
    }

    // List the keys in the reverse-order of the internal buffer, since forEach() is iterating in
    // reverse also:
    final KTypeArrayList<KType> keyList = new KTypeArrayList<KType>();

    keyList.add(this.keyE);

    for (int i = getKeys(newSet).length - 1; i >= 0; i--) {

      if (is_allocated(i, Intrinsics.<KType[]>cast(getKeys(newSet)))) {

        keyList.add(Intrinsics.<KType>cast(getKeys(newSet)[i]));
      }
    }

    // Test forEach predicate and stop at each key in turn.
    final KTypeArrayList<KType> keyListTest = new KTypeArrayList<KType>();

    keyListTest.clear();

    // A) Run forEach(KType)

    newSet.forEach(
        new KTypeProcedure<KType>() {

          @Override
          public void apply(final KType key) {
            keyListTest.add(key);
          }
        });

    // check that keyList/keyListTest and valueList/valueListTest are identical.
    Assert.assertEquals(keyList, keyListTest);
  }
  @Test
  public void testPooledIteratorForEach() {
    // A) Unbroken for-each loop
    // must accommodate even the smallest primitive type
    // so that the iteration do not break before it should...
    final int TEST_SIZE = 126;
    final long TEST_ROUNDS = 5000;

    final KTypeSet<KType> testContainer = createSetWithOrderedData(TEST_SIZE);

    final long checksum =
        testContainer.forEach(
                new KTypeProcedure<KType>() {

                  long count;

                  @Override
                  public void apply(final KType value) {

                    this.count += castType(value);
                  }
                })
            .count;

    long testValue = 0;
    final long initialPoolSize = getEntryPoolSize(testContainer);

    for (int round = 0; round < TEST_ROUNDS; round++) {
      // for-each in test :
      testValue = 0;
      for (final KTypeCursor<KType> cursor : testContainer) {
        // we consume 1 iterator for this loop
        Assert.assertEquals(initialPoolSize - 1, getEntryPoolSize(testContainer));

        testValue += castType(cursor.value);
      }

      // check checksum the iteration
      Assert.assertEquals(checksum, testValue);

      // iterator is returned to its pool
      Assert.assertEquals(initialPoolSize, getEntryPoolSize(testContainer));
    } // end for rounds
  }
  @Test
  public void testAdd() {
    Assert.assertTrue(this.set.add(this.key1));
    Assert.assertFalse(this.set.add(this.key1));
    Assert.assertEquals(1, this.set.size());

    Assert.assertTrue(this.set.add(this.keyE));
    Assert.assertFalse(this.set.add(this.keyE));

    Assert.assertEquals(2, this.set.size());

    Assert.assertTrue(this.set.add(this.key2));
    Assert.assertFalse(this.set.add(this.key2));

    Assert.assertEquals(3, this.set.size());
  }
  @Test
  public void testPooledIteratorBrokenForEach() {
    // A) for-each loop interrupted

    // must accommodate even the smallest primitive type
    // so that the iteration do not break before it should...
    final int TEST_SIZE = 126;
    final long TEST_ROUNDS = 5000;

    final KTypeSet<KType> testContainer = createSetWithOrderedData(TEST_SIZE);

    int count = 0;
    for (int round = 0; round < TEST_ROUNDS; round++) {
      // for-each in test :
      final long initialPoolSize = getEntryPoolSize(testContainer);

      count = 0;
      int guard = 0;
      for (final KTypeCursor<KType> cursor : testContainer) {
        guard += castType(cursor.value);
        // we consume 1 iterator for this loop, but reallocs can happen,
        // so we can only say its != initialPoolSize
        Assert.assertTrue(initialPoolSize != getEntryPoolSize(testContainer));

        // brutally interrupt in the middle
        if (count > TEST_SIZE / 2) {
          break;
        }

        count++;
      } // end for-each

      // iterator is NOT returned to its pool, due to the break.
      // reallocation could happen, so that the only testable thing
      // is that the size is != full pool
      Assert.assertTrue(initialPoolSize != getEntryPoolSize(testContainer));
    } // end for rounds

    // Due to policy of the Iterator pool, the intended pool never get bigger that some limit
    // despite the Iterator leak.
    Assert.assertTrue(getEntryPoolCapacity(testContainer) < IteratorPool.getMaxPoolSize() + 1);
  }
  @Test
  public void testInitialCapacityAndGrowth() {
    for (int i = 0; i < 256; i++) {
      final KTypeSet<KType> set = createNewSetInstance(i, HashContainers.MAX_LOAD_FACTOR);

      for (int j = 0; j < i; j++) {
        set.add(cast(j));
      }

      Assert.assertEquals(i, set.size());
    }
  }
  @Test
  public void testRemoveAllWithPredicateInterrupted() {
    addFromArray(
        this.set,
        newArray(this.k0, this.k1, this.k2, this.k3, this.k4, this.k5, this.k6, this.k7, this.k8));

    final RuntimeException t = new RuntimeException();
    try {
      // the assert below should never be triggered because of the exception
      // so give it an invalid value in case the thing terminates  = initial size + 1
      Assert.assertEquals(
          10,
          this.set.removeAll(
              new KTypePredicate<KType>() {
                @Override
                public boolean apply(final KType v) {
                  if (v == AbstractKTypeHashSetTest.this.key7) {
                    throw t;
                  }
                  return v == AbstractKTypeHashSetTest.this.key2
                      || v == AbstractKTypeHashSetTest.this.key9
                      || v == AbstractKTypeHashSetTest.this.key5;
                };
              }));

      Assert.fail();
    } catch (final RuntimeException e) {
      // Make sure it's really our exception...
      if (e != t) {
        throw e;
      }
    }

    // And check if the set is in consistent state. We cannot predict the pattern,
    // but we know that since key7 throws an exception, key7 is still present in the set.

    Assert.assertTrue(this.set.contains(this.key7));
    checkConsistency();
  }
  @Test
  public void testRemoveAllWithPredicate() {
    addFromArray(this.set, newArray(this.k0, this.k1, this.k2));

    Assert.assertEquals(
        1,
        this.set.removeAll(
            new KTypePredicate<KType>() {
              @Override
              public boolean apply(final KType v) {
                return v == AbstractKTypeHashSetTest.this.k1;
              };
            }));

    TestUtils.assertSortedListEquals(this.set.toArray(), this.k0, this.k2);
  }
  /*! #if ($TemplateOptions.isKType("int", "short", "byte", "long", "Object")) !*/
  @Test
  public void testToString() {
    Assume.assumeTrue(
        int[].class.isInstance(getKeys(this.set))
            || short[].class.isInstance(getKeys(this.set))
            || byte[].class.isInstance(getKeys(this.set))
            || long[].class.isInstance(getKeys(this.set))
            || Object[].class.isInstance(getKeys(this.set)));

    addFromArray(this.set, this.key1, this.key2);
    String asString = this.set.toString();
    asString = asString.replaceAll("[\\[\\],\\ ]", "");
    final char[] asCharArray = asString.toCharArray();
    Arrays.sort(asCharArray);
    Assert.assertEquals("12", new String(asCharArray));
  }
  @Test
  public void testRemoveAllWithPredicate2() {
    addFromArray(this.set, this.keyE, this.key1, this.key2, this.key4);

    Assert.assertEquals(
        2,
        this.set.removeAll(
            new KTypePredicate<KType>() {
              @Override
              public boolean apply(final KType v) {
                return (v == AbstractKTypeHashSetTest.this.key1)
                    || (v == AbstractKTypeHashSetTest.this.keyE);
              };
            }));

    TestUtils.assertSortedListEquals(this.set.toArray(), this.key2, this.key4);
  }
  @Test
  public void testRetainAllWithPredicate2() {
    addFromArray(this.set, newArray(this.keyE, this.k1, this.k2, this.k3, this.k4, this.k5));

    Assert.assertEquals(
        4,
        this.set.retainAll(
            new KTypePredicate<KType>() {
              @Override
              public boolean apply(final KType v) {
                return v == AbstractKTypeHashSetTest.this.keyE
                    || v == AbstractKTypeHashSetTest.this.k3;
              };
            }));

    TestUtils.assertSortedListEquals(this.set.toArray(), this.keyE, this.k3);
  }
  @Test
  /*! #if ($TemplateOptions.KTypeGeneric) !*/
  @SuppressWarnings("unchecked")
  /*! #end !*/
  public void testHashCodeEquals() {
    final KTypeSet<KType> l0 = getFrom();
    Assert.assertEquals(0, l0.hashCode());
    Assert.assertEquals(l0, createNewSetInstance());

    final KTypeSet<KType> l1 = getFrom(this.k1, this.k2, this.k3);
    final KTypeSet<KType> l2 = getFrom(this.k1, this.k2);
    l2.add(this.k3);

    Assert.assertEquals(l1.hashCode(), l2.hashCode());
    Assert.assertEquals(l1, l2);

    l1.add(this.keyE);
    l2.add(this.keyE);

    Assert.assertEquals(l1.hashCode(), l2.hashCode());
    Assert.assertEquals(l1, l2);
  }
 @Test
 public void testInitiallyEmpty() {
   Assert.assertEquals(0, this.set.size());
 }
  @Test
  public void testForEachProcedureWithException() {

    // Test that the container do not resize if less that the initial size

    // 1) Choose a map to build
    /*! #if ($TemplateOptions.isKType("GENERIC", "int", "long", "float", "double")) !*/
    final int NB_ELEMENTS = 2000;
    /*!
    #elseif ($TemplateOptions.isKType("short", "char"))
     int NB_ELEMENTS = 1000;
    #else
      int NB_ELEMENTS = 126;
    #end !*/

    final KTypeSet<KType> newSet = createNewSetInstance();

    newSet.add(this.keyE);

    // add a increasing number of key
    for (int i = 0; i < NB_ELEMENTS; i++) {

      final int KVpair = i;

      newSet.add(cast(KVpair));
    }

    // List the keys in the reverse-order of the internal buffer, since forEach() is iterating in
    // reverse also:
    final KTypeArrayList<KType> keyList = new KTypeArrayList<KType>();

    keyList.add(this.keyE);

    // Test forEach predicate and stop at each key in turn.
    final KTypeArrayList<KType> keyListTest = new KTypeArrayList<KType>();

    for (int k = getKeys(newSet).length - 1; k >= 0; k--) {

      if (is_allocated(k, Intrinsics.<KType[]>cast(getKeys(newSet)))) {

        keyList.add(Intrinsics.<KType>cast(getKeys(newSet)[k]));
      }
    }

    final int size = keyList.size();

    for (int i = 0; i < size; i++) {
      final int currentPairIndexSizeToIterate = i + 1;

      keyListTest.clear();

      keyList.clear();

      keyList.add(this.keyE);

      for (int k = getKeys(newSet).length - 1; k >= 0; k--) {

        if (is_allocated(k, Intrinsics.<KType[]>cast(getKeys(newSet)))) {

          keyList.add(Intrinsics.<KType>cast(getKeys(newSet)[k]));
        }
      }

      // A) Run forEach(KType)
      try {
        newSet.forEach(
            new KTypeProcedure<KType>() {

              @Override
              public void apply(final KType key) {
                keyListTest.add(key);

                // when the stopping key/value pair is encountered, add to list and stop iteration
                if (key == keyList.get(currentPairIndexSizeToIterate - 1)) {
                  // interrupt iteration by an exception
                  throw new RuntimeException("Interrupted treatment by test");
                }
              }
            });
      } catch (final RuntimeException e) {
        if (!e.getMessage().equals("Interrupted treatment by test")) {
          throw e;
        }
      } finally {
        // despite the exception, the procedure terminates cleanly

        // check that keyList/keyListTest and valueList/valueListTest are identical for the first
        // currentPairIndexToIterate + 1 elements
        Assert.assertEquals("i = " + i, currentPairIndexSizeToIterate, keyListTest.size());

        for (int j = 0; j < currentPairIndexSizeToIterate; j++) {
          TestUtils.assertEquals2("j = " + j, keyList.get(j), keyListTest.get(j));
        }
      } // end finally
    } // end for each index
  }
  @Test
  public void testPooledIteratorExceptionIteratorLoop() {
    // must accommodate even the smallest primitive type
    // so that the iteration do not break before it should...
    final int TEST_SIZE = 126;
    final long TEST_ROUNDS = 5000;

    final KTypeSet<KType> testContainer = createSetWithOrderedData(TEST_SIZE);

    final long checksum =
        testContainer.forEach(
                new KTypeProcedure<KType>() {

                  long count;

                  @Override
                  public void apply(final KType value) {
                    this.count += castType(value);
                  }
                })
            .count;

    final int startingPoolSize = getEntryPoolSize(testContainer);

    int count = 0;
    AbstractIterator<KTypeCursor<KType>> loopIterator = null;

    for (int round = 0; round < TEST_ROUNDS; round++) {
      try {
        loopIterator = (AbstractIterator<KTypeCursor<KType>>) testContainer.iterator();

        Assert.assertEquals(startingPoolSize - 1, getEntryPoolSize(testContainer));

        int guard = 0;
        count = 0;
        while (loopIterator.hasNext()) {
          guard += castType(loopIterator.next().value);

          // brutally interrupt in the middle some of the loops, but not all
          if (round > TEST_ROUNDS / 2 && count > TEST_SIZE / 2) {
            throw new Exception("Oups some problem in the loop occured");
          }
          count++;
        } // end while

        // iterator is returned to its pool in case of normal loop termination
        Assert.assertEquals(startingPoolSize, getEntryPoolSize(testContainer));
        Assert.assertEquals(checksum, guard);

      } catch (final Exception e) {
        // iterator is NOT returned to its pool because of the exception
        Assert.assertEquals(startingPoolSize - 1, getEntryPoolSize(testContainer));

        // manual return to the pool then
        loopIterator.release();

        // now the pool is restored
        Assert.assertEquals(startingPoolSize, getEntryPoolSize(testContainer));
      }
    } // end for rounds

    // pool initial size is untouched anyway
    Assert.assertEquals(startingPoolSize, getEntryPoolSize(testContainer));
  }
  @Test
  /*! #if ($TemplateOptions.KTypeGeneric) !*/
  @SuppressWarnings("unchecked")
  /*! #end !*/
  public void testEquals() {
    final KTypeSet<KType> l0 = getFrom();
    Assert.assertEquals(l0, createNewSetInstance());

    KTypeSet<KType> l1 = getFrom(this.k1, this.k2, this.k3, this.k4, this.k5);
    KTypeSet<KType> l2 = getFrom(this.k2, this.k1);

    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    Assert.assertFalse(l1.equals(null));
    Assert.assertFalse(l2.equals(null));

    l2.add(this.k5);
    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    l2.add(this.k4);
    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    l2.add(this.k3);
    Assert.assertEquals(l1, l2);
    Assert.assertEquals(l2, l1);
    // Check consistency with hashCode:
    Assert.assertEquals(l1.hashCode(), l2.hashCode());

    l1.add(this.keyE);
    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    l2.add(this.keyE);

    Assert.assertEquals(l1, l2);
    Assert.assertEquals(l2, l1);
    // Check consistency with hashCode:
    Assert.assertEquals(l1.hashCode(), l2.hashCode());

    l2.remove(this.keyE);

    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    l2.add(this.keyE);

    Assert.assertEquals(l1, l2);
    Assert.assertEquals(l2, l1);
    // Check consistency with hashCode:
    Assert.assertEquals(l1.hashCode(), l2.hashCode());

    l2.remove(this.k7); // not present, sets are still OK
    Assert.assertEquals(l1, l2);
    Assert.assertEquals(l2, l1);
    // Check consistency with hashCode:
    Assert.assertEquals(l1.hashCode(), l2.hashCode());

    l2.remove(this.k2);

    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    l1.remove(this.k2);
    Assert.assertEquals(l1, l2);
    Assert.assertEquals(l2, l1);
    // Check consistency with hashCode:
    Assert.assertEquals(l1.hashCode(), l2.hashCode());

    l1.add(this.k7);
    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    l2.clear();
    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);

    l1.clear();
    Assert.assertEquals(l1, l2);
    Assert.assertEquals(l2, l1);
    // Check consistency with hashCode:
    Assert.assertEquals(l1.hashCode(), l2.hashCode());

    // Same size, different contents
    l1 = getFrom(this.k1, this.k2, this.k3, this.k4, this.k5);
    l2 = getFrom(this.k2, this.k1, this.key5, this.key6, this.key7);

    Assert.assertNotEquals(l1, l2);
    Assert.assertNotEquals(l2, l1);
  }
  @Repeat(iterations = 25)
  @Seed("88DC7A1093FD66C5")
  @Test
  public void testNoOverallocation() {

    final Random randomVK = RandomizedTest.getRandom();
    // Test that the container do not resize if less that the initial size

    // 1) Choose a random number of elements
    /*! #if ($TemplateOptions.isKType("GENERIC", "INT", "LONG", "FLOAT", "DOUBLE")) !*/
    final int PREALLOCATED_SIZE = randomVK.nextInt(10000);
    /*!
    #elseif ($TemplateOptions.isKType("SHORT", "CHAR"))
     int PREALLOCATED_SIZE = randomVK.nextInt(126);
    #else
      int PREALLOCATED_SIZE = randomVK.nextInt(10000);
    #end !*/

    // 2) Preallocate to PREALLOCATED_SIZE, use default factor because copy-constructor use this.
    final KTypeSet<KType> refContainer =
        createNewSetInstance(PREALLOCATED_SIZE, HashContainers.DEFAULT_LOAD_FACTOR);

    final int refCapacity = refContainer.capacity();

    // 3) Fill with random values, random number of elements below preallocation
    final int nbElements = RandomizedTest.randomInt(PREALLOCATED_SIZE);

    for (int i = 0; i < nbElements; i++) {

      refContainer.add(cast(i));
    }

    // Capacity must have not changed, i.e no reallocation must have occured.
    Assert.assertEquals(refCapacity, refContainer.capacity());

    final int nbRefElements = refContainer.size();

    Assert.assertEquals(refCapacity, refContainer.capacity());

    // 4) Duplicate by copy-construction and/or clone
    KTypeSet<KType> clonedContainer = getClone(refContainer);
    KTypeSet<KType> copiedContainer = getCopyConstructor(refContainer);

    final int copiedCapacity = copiedContainer.capacity();
    final int clonedCapacity = copiedContainer.capacity();

    Assert.assertEquals(nbRefElements, clonedContainer.size());
    Assert.assertEquals(nbRefElements, copiedContainer.size());
    // Due to different pre-sizings, clones and copy constructed may or may not have the same
    // capacity as the refContainer.
    Assert.assertTrue(clonedContainer.equals(refContainer));
    Assert.assertTrue(copiedContainer.equals(refContainer));

    // Maybe we were lucky, iterate duplication over itself several times
    for (int j = 0; j < 10; j++) {

      clonedContainer = getClone(clonedContainer);
      copiedContainer = getFrom(copiedContainer);

      // when copied over itself, of course every characteristic must be constant, else something is
      // wrong.
      Assert.assertEquals("j = " + j, nbRefElements, clonedContainer.size());
      Assert.assertEquals("j = " + j, nbRefElements, copiedContainer.size());
      Assert.assertEquals("j = " + j, clonedCapacity, clonedContainer.capacity());
      Assert.assertEquals("j = " + j, copiedCapacity, copiedContainer.capacity());
      Assert.assertTrue("j = " + j, clonedContainer.equals(refContainer));
      Assert.assertTrue("j = " + j, copiedContainer.equals(refContainer));
    }
  }