@Test
  public void testEnumIterator() {
    @SuppressWarnings("unchecked")
    Iterator<String> iterator =
        CollectionUtil.iterator((Enumeration) new StringTokenizer("foo, bar, baz", ", "));

    int count = 0;
    for (Object stringObject : stringObjects) {
      assertTrue(iterator.hasNext());
      assertEquals(stringObject, iterator.next());

      try {
        iterator.remove();
        fail("Enumeration has no remove method, iterator.remove() must throw exception");
      } catch (UnsupportedOperationException expected) {
      }

      count++;
    }

    assertEquals(3, count);
    assertFalse(iterator.hasNext());

    try {
      iterator.next();
      fail("Iterator has more elements than enumeration");
    } catch (NoSuchElementException expected) {
    }
  }
  @Test
  public void testReverseOrderRandomIntegers() {
    Comparator<Integer> naturalOrder = new NaturalOrder<Integer>();
    Comparator<Integer> reverse = CollectionUtil.reverseOrder(naturalOrder);

    Random random = new Random(243249878l); // Stable "random" sequence

    for (int i = 0; i < 65536; i++) {
      // Verified to be ~ 50/50 lt/gt
      int integer = random.nextInt();
      int integerToo = random.nextInt();

      assertEquals(0, reverse.compare(integer, integer));
      assertEquals(0, reverse.compare(integerToo, integerToo));

      int natural = naturalOrder.compare(integer, integerToo);

      if (natural == 0) {
        // Actually never hits, but eq case is tested above
        assertEquals(0, reverse.compare(integer, integerToo));
      } else if (natural < 0) {
        assertTrue(reverse.compare(integer, integerToo) > 0);
      } else {
        assertTrue(reverse.compare(integer, integerToo) < 0);
      }
    }
  }
  @Test(expected = ArrayStoreException.class)
  public void testMergeArraysObjectIllegalType() {
    String[] strings = {"foo", "bar", "baz"};
    Integer[] integers = {1, 2, 3}; // Integer not assignable to String

    CollectionUtil.mergeArrays(strings, integers);
  }
  @Test(expected = ArrayStoreException.class)
  public void testMergeArraysNativeIllegalType() {
    char[] chars = {'a', 'b', 'c'};
    int[] integers = {1, 2, 3}; // Integer not assignable to String

    CollectionUtil.mergeArrays(chars, integers);
  }
  @Test
  public void testArrayIterator() {
    Iterator<String> iterator = CollectionUtil.iterator(new String[] {"foo", "bar", "baz"});

    int count = 0;
    for (Object stringObject : stringObjects) {
      assertTrue(iterator.hasNext());
      assertEquals(stringObject, iterator.next());

      try {
        iterator.remove();
        fail("Array have fixed length, iterator.remove() must throw exception");
      } catch (UnsupportedOperationException expected) {
      }

      count++;
    }

    assertEquals(3, count);
    assertFalse(iterator.hasNext());

    try {
      iterator.next();
      fail("Iterator has more elements than array");
    } catch (NoSuchElementException expected) {
    }
  }
  @Test
  public void testMergeArraysObjectAssignable() {
    Integer[] integers = {1, 2, 3}; // Integer assignable to Object

    Object[] merged = (Object[]) CollectionUtil.mergeArrays(stringObjects, integers);
    assertArrayEquals(new Object[] {"foo", "bar", "baz", 1, 2, 3}, merged);
  }
  @Ignore("For development only")
  @Test
  @SuppressWarnings({"UnusedDeclaration"})
  public void testGenerify() {
    List list = Collections.singletonList("foo");
    @SuppressWarnings({"unchecked"})
    Set set = new HashSet(list);

    List<String> strs0 = CollectionUtil.generify(list, String.class);
    List<Object> objs0 = CollectionUtil.generify(list, String.class);
    //        List<String> strs01 = CollectionUtil.generify(list, Object.class); // Not okay
    try {
      List<String> strs1 =
          CollectionUtil.generify(set, String.class); // Not ok, runtime CCE unless set is null
    } catch (RuntimeException e) {
      e.printStackTrace();
    }

    try {
      ArrayList<String> strs01 =
          CollectionUtil.generify(list, String.class); // Not ok, runtime CCE unless list is null
    } catch (RuntimeException e) {
      e.printStackTrace();
    }

    Set<String> setstr1 = CollectionUtil.generify(set, String.class);
    Set<Object> setobj1 = CollectionUtil.generify(set, String.class);
    try {
      Set<Object> setobj44 =
          CollectionUtil.generify(list, String.class); // Not ok, runtime CCE unless list is null
    } catch (RuntimeException e) {
      e.printStackTrace();
    }

    List<String> strs2 = CollectionUtil.<List<String>, String>generify2(list);
    List<Object> objs2 = CollectionUtil.<List<Object>, String>generify2(list);
    //        List<String> morestrs = CollectionUtil.<List<Object>, String>generify2(list); // Not
    // ok
    try {
      List<String> strs3 =
          CollectionUtil.<List<String>, String>generify2(
              set); // Not ok, runtime CCE unless set is null
    } catch (RuntimeException e) {
      e.printStackTrace();
    }
  }
  @Test
  public void testMergeArraysNative() {
    char[] chars = {'a', 'b', 'c'};
    char[] more = {'x', 'y', 'z'};

    char[] merged = (char[]) CollectionUtil.mergeArrays(chars, more);
    assertArrayEquals(new char[] {'a', 'b', 'c', 'x', 'y', 'z'}, merged);
  }
  @Test
  public void testSelectRandomSubset() {
    ArrayList<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < 100; i++) {
      list.add(i);
    }

    for (int i = 0; i < 10; i++) {
      List<Integer> subset = CollectionUtil.selectRandomSubset(list, 10);
      // System.out.println(StringUtil.toString(subset));
      assertTrue("length == 10", subset.size() == 10);
    }
  }
  @Test
  public void testReverseOrder() {
    Comparator<String> naturalOrder = new NaturalOrder<String>();
    Comparator<String> reverse = CollectionUtil.reverseOrder(naturalOrder);

    assertNotNull(reverse);

    assertEquals(0, naturalOrder.compare("foo", "foo"));
    assertEquals(0, reverse.compare("foo", "foo"));

    assertTrue(naturalOrder.compare("bar", "baz") < 0);
    assertTrue(reverse.compare("bar", "baz") > 0);

    assertTrue(naturalOrder.compare("baz", "bar") > 0);
    assertTrue(reverse.compare("baz", "bar") < 0);
  }
  @Test
  public void testArrayIteratorRange() {
    Iterator<String> iterator =
        CollectionUtil.iterator(new String[] {"foo", "bar", "baz", "xyzzy"}, 1, 2);

    for (int i = 1; i < 3; i++) {
      assertTrue(iterator.hasNext());
      assertEquals(stringObjects[i], iterator.next());

      try {
        iterator.remove();
        fail("Array has no remove method, iterator.remove() must throw exception");
      } catch (UnsupportedOperationException expected) {
      }
    }

    assertFalse(iterator.hasNext());

    try {
      iterator.next();
      fail("Iterator has more elements than array range");
    } catch (NoSuchElementException expected) {
    }
  }
 @Test
 public void testArrayListIteratorRange() {
   assertCorrectListIterator(
       CollectionUtil.iterator(new String[] {"foo", "bar", "baz", "boo"}, 1, 2),
       new String[] {"bar", "baz"});
 }
 @Test(expected = IndexOutOfBoundsException.class)
 public void testMergeArraysObjectNegativeSecondLength() {
   CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 2, -1);
 }
 @Test(expected = IndexOutOfBoundsException.class)
 public void testMergeArraysObjectBadSecondOffset() {
   CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 4, 1);
 }
 @Test
 public void testMergeArraysObjectOffset() {
   Object[] merged =
       (Object[]) CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 2, 1);
   assertArrayEquals(new Object[] {"bar", "baz", 3}, merged);
 }
 @Test
 public void testSubArrayObject() {
   String[] strings = CollectionUtil.subArray(new String[] {"foo", "bar", "baz", "xyzzy"}, 1, 2);
   assertArrayEquals(new String[] {"bar", "baz"}, strings);
 }
 @Test
 public void testSubArrayNative() {
   int[] numbers = (int[]) CollectionUtil.subArray(new int[] {1, 2, 3, 4, 5}, 1, 3);
   assertArrayEquals(new int[] {2, 3, 4}, numbers);
 }
 @Test(expected = IllegalArgumentException.class)
 public void testReverseOrderNull() {
   CollectionUtil.reverseOrder(null);
 }
 @Test(expected = IllegalArgumentException.class)
 public void testArrayIteratorRangeBadLength() {
   CollectionUtil.iterator(stringObjects, 1, stringObjects.length);
 }
 @Test(expected = IllegalArgumentException.class)
 public void testArrayIteratorRangeNull() {
   CollectionUtil.iterator(null, 0, 0);
 }
 @Test(expected = IllegalArgumentException.class)
 public void testEnumIteratorNull() {
   CollectionUtil.iterator((Enumeration<Object>) null);
 }
 @Test
 public void testArrayListIterator() {
   assertCorrectListIterator(
       CollectionUtil.iterator(new String[] {"foo", "bar", "baz"}), stringObjects);
 }
 @Test(expected = IllegalArgumentException.class)
 public void testArrayIteratorNull() {
   CollectionUtil.iterator((Object[]) null);
 }