// CHECKSTYLE_OFF: Copyrighted to ASF
/*
 * Copyright 1999-2004 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// CHECKSTYLE_ON
package com.google.gwt.emultest.java.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

/**
 * Tests base {@link java.util.Collection} methods and contracts.
 *
 * <p>You should create a concrete subclass of this class to test any custom {@link Collection}
 * implementation. At minimum, you'll have to implement the {@link #makeCollection()} method. You
 * might want to override some of the additional protected methods as well:
 *
 * <p><B>Element Population Methods</B>
 *
 * <p>Override these if your collection restricts what kind of elements are allowed (for instance,
 * if <Code>null</Code> is not permitted):
 *
 * <UL>
 *   <Li>{@link #getFullElements()}
 *   <Li>{@link #getOtherElements()}
 * </UL>
 *
 * <B>Supported Operation Methods</B>
 *
 * <p>Override these if your collection doesn't support certain operations:
 *
 * <UL>
 *   <LI>{@link #isAddSupported()}
 *   <LI>{@link #isRemoveSupported()}
 *   <li>{@link #areEqualElementsDistinguishable()}
 * </UL>
 *
 * <B>Fixture Methods</B>
 *
 * <p>Fixtures are used to verify that the operation results in correct state for the collection.
 * Basically, the operation is performed against your collection implementation, and an identical
 * operation is performed against a <I>confirmed</I> collection implementation. A confirmed
 * collection implementation is something like <Code>java.util.ArrayList</Code>, which is known to
 * conform exactly to its collection interface's contract. After the operation takes place on both
 * your collection implementation and the confirmed collection implementation, the two collections
 * are compared to see if their state is identical. The comparison is usually much more involved
 * than a simple <Code>equals</Code> test. This verification is used to ensure proper modifications
 * are made along with ensuring that the collection does not change when read-only modifications are
 * made.
 *
 * <p>The {@link #collection} field holds an instance of your collection implementation; the {@link
 * #confirmed} field holds an instance of the confirmed collection implementation. The {@link
 * #resetEmpty()} and {@link #resetFull()} methods set these fields to empty or full collections, so
 * that tests can proceed from a known state.
 *
 * <p>After a modification operation to both {@link #collection} and {@link #confirmed}, the {@link
 * #verify()} method is invoked to compare the results. You may want to override {@link #verify()}
 * to perform additional verifications. For instance, when testing the collection views of a map,
 * {@link TestMap} would override {@link #verify()} to make sure the map is changed after the
 * collection view is changed.
 *
 * <p>If you're extending this class directly, you will have to provide implementations for the
 * following:
 *
 * <UL>
 *   <LI>{@link #makeConfirmedCollection()}
 *   <LI>{@link #makeConfirmedFullCollection()}
 * </UL>
 *
 * Those methods should provide a confirmed collection implementation that's compatible with your
 * collection implementation.
 *
 * <p>If you're extending {@link TestList}, {@link TestSet}, or {@link TestBag}, you probably don't
 * have to worry about the above methods, because those three classes already override the methods
 * to provide standard JDK confirmed collections.
 *
 * <p><B>Other notes</B>
 *
 * <p>If your {@link Collection} fails one of these tests by design, you may still use this base set
 * of cases. Simply override the test case (method) your {@link Collection} fails. For instance, the
 * {@link #testIteratorFailFast()} method is provided since most collections have fail-fast
 * iterators; however, that's not strictly required by the collection contract, so you may want to
 * override that method to do nothing.
 *
 * <p>
 */
@SuppressWarnings({"unchecked", "rawtypes"})
abstract class TestCollection extends TestObject {

  //
  // NOTE:
  //
  // Collection doesn't define any semantics for equals, and recommends you
  // use reference-based default behavior of Object.equals.  (And a test for
  // that already exists in TestObject).  Tests for equality of lists, sets
  // and bags will have to be written in test subclasses.  Thus, there is no
  // tests on Collection.equals nor any for Collection.hashCode.
  //

  // These fields are used by reset() and verify(), and any test
  // method that tests a modification.

  /** A collection instance that will be used for testing. */
  protected Collection collection;

  /**
   * Confirmed collection. This is an instance of a collection that is confirmed to conform exactly
   * to the java.util.Collection contract. Modification operations are tested by performing a mod on
   * your collection, performing the exact same mod on an equivalent confirmed collection, and then
   * calling verify() to make sure your collection still matches the confirmed collection.
   */
  protected Collection confirmed;

  /**
   * Resets the {@link #collection} and {@link #confirmed} fields to empty collections. Invoke this
   * method before performing a modification test.
   */
  protected void resetEmpty() {
    this.collection = makeCollection();
    this.confirmed = makeConfirmedCollection();
  }

  /**
   * Resets the {@link #collection} and {@link #confirmed} fields to full collections. Invoke this
   * method before performing a modification test.
   */
  protected void resetFull() {
    this.collection = makeFullCollection();
    this.confirmed = makeConfirmedFullCollection();
  }

  /**
   * Specifies whether equal elements in the collection are, in fact, distinguishable with
   * information not readily available. That is, if a particular value is to be removed from the
   * collection, then there is one and only one value that can be removed, even if there are other
   * elements which are equal to it.
   *
   * <p>In most collection cases, elements are not distinguishable (equal is equal), thus this
   * method defaults to return false. In some cases, however, they are. For example, the collection
   * returned from the map's values() collection view are backed by the map, so while there may be
   * two values that are equal, their associated keys are not. Since the keys are distinguishable,
   * the values are.
   *
   * <p>This flag is used to skip some verifications for iterator.remove() where it is impossible to
   * perform an equivalent modification on the confirmed collection because it is not possible to
   * determine which value in the confirmed collection to actually remove. Tests that override the
   * default (i.e. where equal elements are distinguishable), should provide additional tests on
   * iterator.remove() to make sure the proper elements are removed when remove() is called on the
   * iterator.
   */
  protected boolean areEqualElementsDistinguishable() {
    return false;
  }

  /** Verifies that {@link #collection} and {@link #confirmed} have identical state. */
  protected void verify() {
    int confirmedSize = confirmed.size();
    assertEquals(
        "Collection size should match confirmed collection's", confirmedSize, collection.size());
    assertEquals(
        "Collection isEmpty() result should match confirmed " + " collection's",
        confirmed.isEmpty(),
        collection.isEmpty());

    // verify the collections are the same by attempting to match each
    // object in the collection and confirmed collection.  To account for
    // duplicates and differing orders, each confirmed element is copied
    // into an array and a flag is maintained for each element to determine
    // whether it has been matched once and only once.  If all elements in
    // the confirmed collection are matched once and only once and there
    // aren't any elements left to be matched in the collection,
    // verification is a success.

    // copy each collection value into an array
    Object[] confirmedValues = new Object[confirmedSize];

    Iterator iter;

    iter = confirmed.iterator();
    int pos = 0;
    while (iter.hasNext()) {
      confirmedValues[pos++] = iter.next();
    }

    // allocate an array of boolean flags for tracking values that have
    // been matched once and only once.
    boolean[] matched = new boolean[confirmedSize];

    // now iterate through the values of the collection and try to match
    // the value with one in the confirmed array.
    iter = collection.iterator();
    while (iter.hasNext()) {
      Object o = iter.next();
      boolean match = false;
      for (int i = 0; i < confirmedSize; i++) {
        if (matched[i]) {
          // skip values already matched
          continue;
        }
        if (o == confirmedValues[i] || (o != null && o.equals(confirmedValues[i]))) {
          // values matched
          matched[i] = true;
          match = true;
          break;
        }
      }
      // no match found!
      if (!match) {
        fail(
            "Collection should not contain a value that the "
                + "confirmed collection does not have.");
      }
    }

    // make sure there aren't any unmatched values
    for (int i = 0; i < confirmedSize; i++) {
      if (!matched[i]) {
        // the collection didn't match all the confirmed values
        fail("Collection should contain all values that are in the " + "confirmed collection");
      }
    }
  }

  /**
   * Returns a confirmed empty collection. For instance, a {@link java.util.ArrayList} for lists or
   * a {@link java.util.HashSet} for sets.
   *
   * @return a confirmed empty collection
   */
  protected abstract Collection makeConfirmedCollection();

  /**
   * Returns a confirmed full collection. For instance, a {@link java.util.ArrayList} for lists or a
   * {@link java.util.HashSet} for sets. The returned collection should contain the elements
   * returned by {@link #getFullElements()}.
   *
   * @return a confirmed full collection
   */
  protected abstract Collection makeConfirmedFullCollection();

  /**
   * Returns true if the collections produced by {@link #makeCollection()} and {@link
   * #makeFullCollection()} support the <Code>add</Code> and <Code>addAll</Code> operations.
   *
   * <p>Default implementation returns true. Override if your collection class does not support add
   * or addAll.
   */
  protected boolean isAddSupported() {
    return true;
  }

  /**
   * Returns true if the collections produced by {@link #makeCollection()} and {@link
   * #makeFullCollection()} support the <Code>remove</Code>, <Code>removeAll</Code>, <Code>retainAll
   * </Code>, <Code>clear</Code> and <Code>iterator().remove()</Code> methods. Default
   * implementation returns true. Override if your collection class does not support removal
   * operations.
   */
  protected boolean isRemoveSupported() {
    return true;
  }

  /**
   * Returns an array of objects that are contained in a collection produced by {@link
   * #makeFullCollection()}. Every element in the returned array <I>must</I> be an element in a full
   * collection.
   *
   * <p>The default implementation returns a heterogeneous array of objects with some duplicates and
   * with the null element. Override if you require specific testing elements. Note that if you
   * override {@link #makeFullCollection()}, you <I>must</I> override this method to reflect the
   * contents of a full collection.
   */
  protected Object[] getFullElements() {
    ArrayList list = new ArrayList();

    list.addAll(Arrays.asList(getFullNonNullElements()));
    list.add(4, null);
    return list.toArray();
  }

  /**
   * Returns an array of elements that are <I>not</I> contained in a full collection. Every element
   * in the returned array must not exist in a collection returned by {@link #makeFullCollection()}.
   * The default implementation returns a heterogeneous array of elements without null. Note that
   * some of the tests add these elements to an empty or full collection, so if your collection
   * restricts certain kinds of elements, you should override this method.
   */
  protected Object[] getOtherElements() {
    return getOtherNonNullElements();
  }

  /** Returns a new, empty {@link Collection} to be used for testing. */
  protected abstract Collection makeCollection();

  /**
   * Returns a full collection to be used for testing. The collection returned by this method should
   * contain every element returned by {@link #getFullElements()}. The default implementation, in
   * fact, simply invokes <Code>addAll</Code> on an empty collection with the results of {@link
   * #getFullElements()}. Override this default if your collection doesn't support addAll.
   */
  protected Collection makeFullCollection() {
    Collection c = makeCollection();
    c.addAll(Arrays.asList(getFullElements()));
    return c;
  }

  /** Returns an empty collection for Object tests. */
  @Override
  public Object makeObject() {
    return makeCollection();
  }

  /** Tests {@link Collection#add(Object)}. */
  public void testCollectionAdd() {
    if (!isAddSupported()) {
      return;
    }

    Object[] elements = getFullElements();
    for (int i = 0; i < elements.length; i++) {
      resetEmpty();
      boolean r = collection.add(elements[i]);
      confirmed.add(elements[i]);
      verify();
      assertTrue("Empty collection changed after add", r);
      assertTrue("Collection size is 1 after first add", collection.size() == 1);
    }

    resetEmpty();
    int size = 0;
    for (int i = 0; i < elements.length; i++) {
      boolean r = collection.add(elements[i]);
      confirmed.add(elements[i]);
      verify();
      if (r) {
        size++;
      }
      assertEquals("Collection size should grow after add", size, collection.size());
      assertTrue("Collection should contain added element", collection.contains(elements[i]));
    }
  }

  /** Tests {@link Collection#addAll(Collection)}. */
  public void testCollectionAddAll() {
    if (!isAddSupported()) {
      return;
    }

    resetEmpty();
    Object[] elements = getFullElements();
    boolean r = collection.addAll(Arrays.asList(elements));
    confirmed.addAll(Arrays.asList(elements));
    verify();
    assertTrue("Empty collection should change after addAll", r);
    for (int i = 0; i < elements.length; i++) {
      assertTrue("Collection should contain added element", collection.contains(elements[i]));
    }

    resetFull();
    int size = collection.size();
    elements = getOtherElements();
    r = collection.addAll(Arrays.asList(elements));
    confirmed.addAll(Arrays.asList(elements));
    verify();
    assertTrue("Full collection should change after addAll", r);
    for (int i = 0; i < elements.length; i++) {
      assertTrue("Full collection should contain added element", collection.contains(elements[i]));
    }
    assertEquals("Size should increase after addAll", size + elements.length, collection.size());

    resetFull();
    size = collection.size();
    r = collection.addAll(Arrays.asList(getFullElements()));
    confirmed.addAll(Arrays.asList(getFullElements()));
    verify();
    if (r) {
      assertTrue("Size should increase if addAll returns true", size < collection.size());
    } else {
      assertEquals("Size should not change if addAll returns false", size, collection.size());
    }
  }

  /**
   *  If {@link #isAddSupported()} returns false, tests that add operations
   *  raise <Code>UnsupportedOperationException.
   */
  public void testUnsupportedAdd() {
    if (isAddSupported()) {
      return;
    }

    resetEmpty();
    try {
      collection.add(new Object());
      fail("Emtpy collection should not support add.");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    // make sure things didn't change even if the expected exception was
    // thrown.
    verify();

    try {
      collection.addAll(Arrays.asList(getFullElements()));
      fail("Emtpy collection should not support addAll.");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    // make sure things didn't change even if the expected exception was
    // thrown.
    verify();

    resetFull();
    try {
      collection.add(new Object());
      fail("Full collection should not support add.");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    // make sure things didn't change even if the expected exception was
    // thrown.
    verify();

    try {
      collection.addAll(Arrays.asList(getOtherElements()));
      fail("Full collection should not support addAll.");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    // make sure things didn't change even if the expected exception was
    // thrown.
    verify();
  }

  /** Test {@link Collection#clear()}. */
  public void testCollectionClear() {
    if (!isRemoveSupported()) {
      return;
    }

    resetEmpty();
    collection.clear(); // just to make sure it doesn't raise anything
    verify();

    resetFull();
    collection.clear();
    confirmed.clear();
    verify();
  }

  /** Tests {@link Collection#contains(Object)}. */
  public void testCollectionContains() {
    Object[] elements;

    resetEmpty();
    elements = getFullElements();
    for (int i = 0; i < elements.length; i++) {
      assertFalse("Empty collection shouldn't contain element", collection.contains(elements[i]));
    }
    // make sure calls to "contains" don't change anything
    verify();

    elements = getOtherElements();
    for (int i = 0; i < elements.length; i++) {
      assertTrue("Empty collection shouldn't contain element", !collection.contains(elements[i]));
    }
    // make sure calls to "contains" don't change anything
    verify();

    resetFull();
    elements = getFullElements();
    for (int i = 0; i < elements.length; i++) {
      assertTrue("Full collection should contain element.", collection.contains(elements[i]));
    }
    // make sure calls to "contains" don't change anything
    verify();

    resetFull();
    elements = getOtherElements();
    for (int i = 0; i < elements.length; i++) {
      assertTrue("Full collection shouldn't contain element", !collection.contains(elements[i]));
    }
  }

  /** Tests {@link Collection#containsAll(Collection)}. */
  @SuppressWarnings("ModifyingCollectionWithItself")
  public void testCollectionContainsAll() {
    resetEmpty();
    Collection col = new HashSet();
    assertTrue(
        "Every Collection should contain all elements of an " + "empty Collection.",
        collection.containsAll(col));
    col.addAll(Arrays.asList(getOtherElements()));
    assertTrue(
        "Empty Collection shouldn't contain all elements of " + "a non-empty Collection.",
        !collection.containsAll(col));
    // make sure calls to "containsAll" don't change anything
    verify();

    resetFull();
    assertTrue("Full collection shouldn't contain other elements", !collection.containsAll(col));

    col.clear();
    col.addAll(Arrays.asList(getFullElements()));
    assertTrue("Full collection should containAll full elements", collection.containsAll(col));
    // make sure calls to "containsAll" don't change anything
    verify();

    assertTrue("Full collection should containAll itself", collection.containsAll(collection));

    // make sure calls to "containsAll" don't change anything
    verify();

    col = new ArrayList();
    col.addAll(Arrays.asList(getFullElements()));
    col.addAll(Arrays.asList(getFullElements()));
    assertTrue(
        "Full collection should containAll duplicate full " + "elements",
        collection.containsAll(col));

    // make sure calls to "containsAll" don't change anything
    verify();
  }

  /** Tests {@link Collection#isEmpty()}. */
  public void testCollectionIsEmpty() {
    resetEmpty();
    assertEquals("New Collection should be empty.", true, collection.isEmpty());
    // make sure calls to "isEmpty() don't change anything
    verify();

    resetFull();
    assertEquals("Full collection shouldn't be empty", false, collection.isEmpty());
    // make sure calls to "isEmpty() don't change anything
    verify();
  }

  /** Tests the read-only functionality of {@link Collection#iterator()}. */
  public void testCollectionIterator() {
    resetEmpty();
    Iterator it1 = collection.iterator();
    assertEquals("Iterator for empty Collection shouldn't have next.", false, it1.hasNext());
    try {
      it1.next();
      fail(
          "Iterator at end of Collection should throw "
              + "NoSuchElementException when next is called.");
    } catch (NoSuchElementException e) {
      // expected
    }
    // make sure nothing has changed after non-modification
    verify();

    resetFull();
    it1 = collection.iterator();
    for (int i = 0; i < collection.size(); i++) {
      assertTrue("Iterator for full collection should haveNext", it1.hasNext());
      it1.next();
    }
    assertTrue("Iterator should be finished", !it1.hasNext());

    ArrayList list = new ArrayList();
    it1 = collection.iterator();
    for (int i = 0; i < collection.size(); i++) {
      Object next = it1.next();
      assertTrue(
          "Collection should contain element returned by " + "its iterator",
          collection.contains(next));
      list.add(next);
    }
    try {
      it1.next();
      fail("iterator.next() should raise NoSuchElementException " + "after it finishes");
    } catch (NoSuchElementException e) {
      // expected
    }
    // make sure nothing has changed after non-modification
    verify();
  }

  /** Tests removals from {@link Collection#iterator()}. */
  public void testCollectionIteratorRemove() {
    if (!isRemoveSupported()) {
      return;
    }

    resetEmpty();
    try {
      collection.iterator().remove();
      fail("New iterator.remove should raise IllegalState");
    } catch (IllegalStateException e) {
      // expected
    }
    verify();

    try {
      Iterator iter = collection.iterator();
      iter.hasNext();
      iter.remove();
      fail("New iterator.remove should raise IllegalState " + "even after hasNext");
    } catch (IllegalStateException e) {
      // expected
    }
    verify();

    resetFull();
    int size = collection.size();
    Iterator iter = collection.iterator();
    while (iter.hasNext()) {
      Object o = iter.next();
      iter.remove();

      // if the elements aren't distinguishable, we can just remove a
      // matching element from the confirmed collection and verify
      // contents are still the same.  Otherwise, we don't have the
      // ability to distinguish the elements and determine which to
      // remove from the confirmed collection (in which case, we don't
      // verify because we don't know how).
      //
      // see areEqualElementsDistinguishable()
      if (!areEqualElementsDistinguishable()) {
        confirmed.remove(o);
        verify();
      }

      size--;
      assertEquals(
          "Collection should shrink by one after " + "iterator.remove", size, collection.size());
    }
    assertTrue("Collection should be empty after iterator purge", collection.isEmpty());

    resetFull();
    iter = collection.iterator();
    iter.next();
    iter.remove();
    try {
      iter.remove();
      fail("Second iter.remove should raise IllegalState");
    } catch (IllegalStateException e) {
      // expected
    }
  }

  /** Tests {@link Collection#remove(Object)}. */
  public void testCollectionRemove() {
    if (!isRemoveSupported()) {
      return;
    }

    resetEmpty();
    Object[] elements = getFullElements();
    for (int i = 0; i < elements.length; i++) {
      assertTrue("Shouldn't remove nonexistent element", !collection.remove(elements[i]));
      verify();
    }

    Object[] other = getOtherElements();

    resetFull();
    for (int i = 0; i < other.length; i++) {
      assertTrue("Shouldn't remove nonexistent other element", !collection.remove(other[i]));
      verify();
    }

    int size = collection.size();
    for (int i = 0; i < elements.length; i++) {
      resetFull();
      assertTrue("Collection should remove extant element", collection.remove(elements[i]));

      // if the elements aren't distinguishable, we can just remove a
      // matching element from the confirmed collection and verify
      // contents are still the same.  Otherwise, we don't have the
      // ability to distinguish the elements and determine which to
      // remove from the confirmed collection (in which case, we don't
      // verify because we don't know how).
      //
      // see areEqualElementsDistinguishable()
      if (!areEqualElementsDistinguishable()) {
        confirmed.remove(elements[i]);
        verify();
      }

      assertEquals("Collection should shrink after remove", size - 1, collection.size());
    }
  }

  /** Tests {@link Collection#removeAll(Collection)}. */
  public void testCollectionRemoveAll() {
    if (!isRemoveSupported()) {
      return;
    }

    resetEmpty();
    assertTrue(
        "Emtpy collection removeAll should return false for " + "empty input",
        !collection.removeAll(Collections.EMPTY_SET));
    verify();

    assertTrue(
        "Emtpy collection removeAll should return false for " + "nonempty input",
        !collection.removeAll(new ArrayList(collection)));
    verify();

    resetFull();
    assertTrue(
        "Full collection removeAll should return false for " + "empty input",
        !collection.removeAll(Collections.EMPTY_SET));
    verify();

    assertTrue(
        "Full collection removeAll should return false for " + "other elements",
        !collection.removeAll(Arrays.asList(getOtherElements())));
    verify();

    assertTrue(
        "Full collection removeAll should return true for " + "full elements",
        collection.removeAll(new HashSet(collection)));
    confirmed.removeAll(new HashSet(confirmed));
    verify();

    resetFull();

    int size = collection.size();
    Object[] s = getFullElements();
    List l = new ArrayList();
    l.add(s[2]);
    l.add(s[3]);
    l.add(s[3]);

    assertTrue("Full collection removeAll should work", collection.removeAll(l));
    confirmed.removeAll(l);
    verify();

    assertTrue("Collection should shrink after removeAll", collection.size() < size);
    Iterator iter = l.iterator();
    while (iter.hasNext()) {
      assertTrue("Collection shouldn't contain removed element", !collection.contains(iter.next()));
    }
  }

  /** Tests {@link Collection#retainAll(Collection)}. */
  public void testCollectionRetainAll() {
    if (!isRemoveSupported()) {
      return;
    }

    resetEmpty();
    List elements = Arrays.asList(getFullElements());
    List other = Arrays.asList(getOtherElements());
    Set empty = new HashSet();

    assertTrue("Empty retainAll() should return false", !collection.retainAll(empty));
    verify();

    assertTrue("Empty retainAll() should return false", !collection.retainAll(elements));
    verify();

    resetFull();
    assertTrue("Collection should change from retainAll empty", collection.retainAll(empty));
    confirmed.retainAll(empty);
    verify();

    resetFull();
    assertTrue("Collection changed from retainAll other", collection.retainAll(other));
    confirmed.retainAll(other);
    verify();

    resetFull();
    int size = collection.size();
    assertTrue(
        "Collection shouldn't change from retainAll elements", !collection.retainAll(elements));
    verify();
    assertEquals("Collection size shouldn't change", size, collection.size());

    resetFull();
    HashSet set = new HashSet(elements);
    size = collection.size();
    assertTrue(
        "Collection shouldn't change from retainAll without " + "duplicate elements",
        !collection.retainAll(set));
    verify();
    assertEquals(
        "Collection size didn't change from nonduplicate " + "retainAll", size, collection.size());
  }

  /** Tests {@link Collection#size()}. */
  public void testCollectionSize() {
    resetEmpty();
    assertEquals("Size of new Collection is 0.", 0, collection.size());

    resetFull();
    assertTrue("Size of full collection should be greater than zero", collection.size() > 0);
  }

  /** Tests <Code>toString</Code> on a collection. */
  public void testCollectionToString() {
    resetEmpty();
    assertTrue("toString shouldn't return null", collection.toString() != null);

    resetFull();
    assertTrue("toString shouldn't return null", collection.toString() != null);
  }

  /**
   * If isRemoveSupported() returns false, tests to see that remove operations raise an
   * UnsupportedOperationException.
   */
  public void testUnsupportedRemove() {
    if (isRemoveSupported()) {
      return;
    }

    resetEmpty();
    try {
      collection.clear();
      fail("clear should raise UnsupportedOperationException");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    verify();

    try {
      collection.remove(null);
      fail("remove should raise UnsupportedOperationException");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    verify();

    try {
      collection.removeAll(null);
      fail("removeAll should raise UnsupportedOperationException");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    verify();

    try {
      collection.retainAll(null);
      fail("removeAll should raise UnsupportedOperationException");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    verify();

    resetFull();
    try {
      Iterator iterator = collection.iterator();
      iterator.next();
      iterator.remove();
      fail("iterator.remove should raise UnsupportedOperationException");
    } catch (UnsupportedOperationException e) {
      // expected
    }
    verify();
  }

  /**
   * Returns a list of elements suitable for return by {@link #getFullElements()}. The array
   * returned by this method does not include null, but does include a variety of objects of
   * different types. Override getFullElements to return the results of this method if your
   * collection does not support the null element.
   */
  public static Object[] getFullNonNullElements() {
    return new Object[] {
      "",
      "One",
      new Integer(2),
      "Three",
      new Integer(4),
      "One",
      new Double(5),
      new Float(6),
      "Seven",
      "Eight",
      "Nine",
      new Integer(10),
      new Short((short) 11),
      new Long(12),
      "Thirteen",
      "14",
      "15",
      new Byte((byte) 16)
    };
  }

  /**
   * Returns the default list of objects returned by {@link #getOtherElements()}. Includes many
   * objects of different types.
   */
  public static Object[] getOtherNonNullElements() {
    return new Object[] {
      new Integer(0),
      new Float(0),
      new Double(0),
      "Zero",
      new Short((short) 0),
      new Byte((byte) 0),
      new Long(0),
      new Character('\u0000'),
      "0"
    };
  }

  /**
   * Returns a list of string elements suitable for return by {@link #getFullElements()}. Override
   * getFullElements to return the results of this method if your collection does not support
   * heterogeneous elements or the null element.
   */
  public static Object[] getFullNonNullStringElements() {
    return new Object[] {
      "If",
      "the",
      "dull",
      "substance",
      "of",
      "my",
      "flesh",
      "were",
      "thought",
      "Injurious",
      "distance",
      "could",
      "not",
      "stop",
      "my",
      "way",
    };
  }

  /**
   * Returns a list of string elements suitable for return by {@link #getOtherElements()}. Override
   * getOtherElements to return the results of this method if your collection does not support
   * heterogeneous elements or the null element.
   */
  public static Object[] getOtherNonNullStringElements() {
    return new Object[] {
      "For", "then", "despite", /* of */ "space", "I", "would", "be", "brought",
      "From", "limits", "far", "remote", "where", "thou", "dost", "stay"
    };
  }
}
