diff --git a/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml b/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
index 151b673..550ef4b 100644
--- a/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
+++ b/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
@@ -15,7 +15,6 @@
 <module>
   <inherits name='com.google.gwt.junit.JUnit' />
   <inherits name='com.google.gwt.testing.TestUtils' />
-  <inherits name='org.apache.commons.Collections' />
   <source path='java' />
   <source path='java8' />
 
diff --git a/user/test/org/apache/commons/collections/AbstractTestListIterator.java b/user/test/com/google/gwt/emultest/java/util/AbstractTestListIterator.java
similarity index 86%
rename from user/test/org/apache/commons/collections/AbstractTestListIterator.java
rename to user/test/com/google/gwt/emultest/java/util/AbstractTestListIterator.java
index 7f61132..2fde145 100755
--- a/user/test/org/apache/commons/collections/AbstractTestListIterator.java
+++ b/user/test/com/google/gwt/emultest/java/util/AbstractTestListIterator.java
@@ -1,3 +1,4 @@
+// CHECKSTYLE_OFF: Copyrighted to ASF
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements. See the NOTICE file distributed with this
@@ -5,18 +6,19 @@
  * licenses this file to You 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.
- * 
- * THIS CODE HAS BEEN EXTENSIVELY HACKED BY GOOGLE TO WORK WITH GWT. 
+ *
+ * THIS CODE HAS BEEN EXTENSIVELY HACKED BY GOOGLE TO WORK WITH GWT.
  */
-package org.apache.commons.collections;
+// CHECKSTYLE_ON
+package com.google.gwt.emultest.java.util;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -25,40 +27,32 @@
 
 /**
  * Abstract class for testing the ListIterator interface.
- * <p>
- * This class provides a framework for testing an implementation of
- * ListIterator. Concrete subclasses must provide the list iterator to be
- * tested. They must also specify certain details of how the list iterator
- * operates by overriding the supportsXxx() methods if necessary.
- * 
- * @since Commons Collections 3.0
- * @version $Revision$ $Date$
- * 
- * @author Rodney Waldhoff
- * @author Stephen Colebourne
+ *
+ * <p>This class provides a framework for testing an implementation of ListIterator. Concrete
+ * subclasses must provide the list iterator to be tested. They must also specify certain details of
+ * how the list iterator operates by overriding the supportsXxx() methods if necessary.
  */
 @SuppressWarnings({"unchecked", "rawtypes"})
-public abstract class AbstractTestListIterator extends TestIterator {
+abstract class AbstractTestListIterator extends TestIterator {
 
   // -----------------------------------------------------------------------
   /**
    * Implement this method to return a list iterator over an empty collection.
-   * 
+   *
    * @return an empty iterator
    */
   public abstract ListIterator makeEmptyListIterator();
 
   /**
-   * Implement this method to return a list iterator over a collection with
-   * elements.
-   * 
+   * Implement this method to return a list iterator over a collection with elements.
+   *
    * @return a full iterator
    */
   public abstract ListIterator makeFullListIterator();
 
   /**
    * Implements the abstract superclass method to return the list iterator.
-   * 
+   *
    * @return an empty iterator
    */
   @Override
@@ -68,7 +62,7 @@
 
   /**
    * Implements the abstract superclass method to return the list iterator.
-   * 
+   *
    * @return a full iterator
    */
   @Override
@@ -77,9 +71,8 @@
   }
 
   /**
-   * Whether or not we are testing an iterator that supports add(). Default is
-   * true.
-   * 
+   * Whether or not we are testing an iterator that supports add(). Default is true.
+   *
    * @return true if Iterator supports add
    */
   public boolean supportsAdd() {
@@ -87,26 +80,21 @@
   }
 
   /**
-   * Whether or not we are testing an iterator that supports set(). Default is
-   * true.
-   * 
+   * Whether or not we are testing an iterator that supports set(). Default is true.
+   *
    * @return true if Iterator supports set
    */
   public boolean supportsSet() {
     return true;
   }
 
-  /**
-   * The value to be used in the add and set tests. Default is null.
-   */
+  /** The value to be used in the add and set tests. Default is null. */
   public Object addSetValue() {
     return null;
   }
 
   // -----------------------------------------------------------------------
-  /**
-   * Test that the empty list iterator contract is correct.
-   */
+  /** Test that the empty list iterator contract is correct. */
   public void testEmptyListIteratorIsIndeedEmpty() {
     if (supportsEmptyIterator() == false) {
       return;
@@ -134,9 +122,7 @@
     }
   }
 
-  /**
-   * Test navigation through the iterator.
-   */
+  /** Test navigation through the iterator. */
   public void testWalkForwardAndBack() {
     ArrayList list = new ArrayList();
     ListIterator it = makeFullListIterator();
@@ -172,9 +158,7 @@
     }
   }
 
-  /**
-   * Test add behaviour.
-   */
+  /** Test add behaviour. */
   public void testAdd() {
     ListIterator it = makeFullListIterator();
 
@@ -209,9 +193,7 @@
     }
   }
 
-  /**
-   * Test set behaviour.
-   */
+  /** Test set behaviour. */
   public void testSet() {
     ListIterator it = makeFullListIterator();
 
@@ -237,7 +219,6 @@
 
     // repeated set calls should be fine
     it.set(addSetValue());
-
   }
 
   public void testRemoveThenSet() {
@@ -267,9 +248,7 @@
     }
   }
 
-  /**
-   * Test remove after add behaviour.
-   */
+  /** Test remove after add behaviour. */
   public void testAddThenRemove() {
     ListIterator it = makeFullListIterator();
 
@@ -284,5 +263,4 @@
       }
     }
   }
-
 }
diff --git a/user/test/com/google/gwt/emultest/java/util/ArrayDequeTest.java b/user/test/com/google/gwt/emultest/java/util/ArrayDequeTest.java
index 988523f..be4db76 100644
--- a/user/test/com/google/gwt/emultest/java/util/ArrayDequeTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/ArrayDequeTest.java
@@ -18,11 +18,7 @@
 import static java.util.Arrays.asList;
 
 import com.google.gwt.core.client.JavaScriptException;
-
 import com.google.gwt.testing.TestUtils;
-
-import org.apache.commons.collections.TestCollection;
-
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -31,9 +27,7 @@
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-/**
- * Tests ArrayDeque class.
- */
+/** Tests ArrayDeque class. */
 public class ArrayDequeTest extends TestCollection {
 
   public void testAdd() throws Exception {
@@ -52,7 +46,8 @@
     try {
       deque.add(null);
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testAddAll() throws Exception {
@@ -67,7 +62,8 @@
       deque = new ArrayDeque<>();
       deque.addAll(asList(o1, null, o2));
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testAddFirst() {
@@ -86,7 +82,8 @@
     try {
       deque.addFirst(null);
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testAddLast() {
@@ -105,7 +102,8 @@
     try {
       deque.addLast(null);
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testConstructorFromCollection() {
@@ -122,7 +120,8 @@
     try {
       new ArrayDeque<>(asList(new Object(), null, new Object()));
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
 
     Collection<Object> collection = new ArrayList<>(asList(getFullNonNullElements()));
     checkDequeSizeAndContent(new ArrayDeque<>(collection), getFullNonNullElements());
@@ -163,7 +162,8 @@
     try {
       it.next();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     deque.add(o2);
@@ -179,7 +179,8 @@
     try {
       it.next();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
     checkDequeSizeAndContent(deque, o1, o2, o3);
 
     deque = new ArrayDeque<>();
@@ -207,7 +208,8 @@
     try {
       deque.element();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     assertEquals(o1, deque.element());
@@ -222,7 +224,8 @@
     try {
       deque.element();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
   }
 
   public void testFailFastIterator() {
@@ -241,7 +244,8 @@
       if (TestUtils.getJdkVersion() < 11) {
         fail();
       }
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
 
     deque = new ArrayDeque<>(asList(getFullNonNullElements()));
     it = deque.iterator();
@@ -250,7 +254,8 @@
     try {
       it.next();
       fail();
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
 
     deque = new ArrayDeque<>(asList(getFullNonNullElements()));
     it = deque.iterator();
@@ -267,7 +272,8 @@
       if (TestUtils.getJdkVersion() < 11) {
         fail();
       }
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
 
     deque = new ArrayDeque<>(asList(getFullNonNullElements()));
     it = deque.iterator();
@@ -291,7 +297,8 @@
       if (TestUtils.getJdkVersion() < 11) {
         fail();
       }
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
   }
 
   public void testFailFastDescendingIterator() {
@@ -310,7 +317,8 @@
       if (TestUtils.getJdkVersion() < 11) {
         fail();
       }
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
 
     deque = new ArrayDeque<>(asList(getFullNonNullElements()));
     it = deque.descendingIterator();
@@ -319,7 +327,8 @@
     try {
       it.next();
       fail();
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
 
     deque = new ArrayDeque<>(asList(getFullNonNullElements()));
     it = deque.descendingIterator();
@@ -336,7 +345,8 @@
     try {
       it.next();
       fail();
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
 
     deque = new ArrayDeque<>(asList(getFullNonNullElements()));
     it = deque.descendingIterator();
@@ -360,7 +370,8 @@
       if (TestUtils.getJdkVersion() < 11) {
         fail();
       }
-    } catch (ConcurrentModificationException expected) { }
+    } catch (ConcurrentModificationException expected) {
+    }
   }
 
   public void testGetFirst() {
@@ -371,7 +382,8 @@
     try {
       deque.getFirst();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     assertEquals(o1, deque.getFirst());
@@ -386,7 +398,8 @@
     try {
       deque.getFirst();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
   }
 
   public void testGetLast() {
@@ -397,7 +410,8 @@
     try {
       deque.getLast();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     assertEquals(o1, deque.getLast());
@@ -412,7 +426,8 @@
     try {
       deque.getLast();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
   }
 
   public void testOffer() {
@@ -431,7 +446,8 @@
     try {
       deque.offer(null);
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testOfferFirst() {
@@ -450,7 +466,8 @@
     try {
       deque.offerFirst(null);
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testOfferLast() {
@@ -469,7 +486,8 @@
     try {
       deque.offerLast(null);
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testPeek() {
@@ -619,7 +637,8 @@
     try {
       deque.pop();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     assertEquals(o1, deque.pop());
@@ -634,7 +653,8 @@
     try {
       deque.pop();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
   }
 
   public void testPush() {
@@ -653,7 +673,8 @@
     try {
       deque.push(null);
       fail();
-    } catch (NullPointerException expected) { }
+    } catch (NullPointerException expected) {
+    }
   }
 
   public void testRemove() {
@@ -664,7 +685,8 @@
     try {
       deque.remove();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     assertEquals(o1, deque.remove());
@@ -680,7 +702,8 @@
     try {
       deque.remove();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
   }
 
   public void testRemoveElement() {
@@ -712,7 +735,8 @@
     try {
       deque.removeFirst();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     assertEquals(o1, deque.removeFirst());
@@ -728,7 +752,8 @@
     try {
       deque.removeFirst();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
   }
 
   public void testRemoveFirstOccurrence() {
@@ -778,7 +803,8 @@
     try {
       deque.removeLast();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
 
     deque.add(o1);
     assertEquals(o1, deque.removeLast());
@@ -794,7 +820,8 @@
     try {
       deque.removeLast();
       fail();
-    } catch (NoSuchElementException expected) { }
+    } catch (NoSuchElementException expected) {
+    }
   }
 
   public void testRemoveLastOccurrence() {
@@ -858,9 +885,7 @@
     assertTrue(deque.isEmpty());
   }
 
-  /**
-   * Null elements are prohibited in ArrayDeque.
-   */
+  /** Null elements are prohibited in ArrayDeque. */
   @Override
   protected Object[] getFullElements() {
     return getFullNonNullElements();
diff --git a/user/test/com/google/gwt/emultest/java/util/ComparatorTest.java b/user/test/com/google/gwt/emultest/java/util/ComparatorTest.java
index 5ed1eec..0bfc0ed 100644
--- a/user/test/com/google/gwt/emultest/java/util/ComparatorTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/ComparatorTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2007 Google Inc.
- * 
+ *
  * 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
@@ -15,15 +15,11 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import org.apache.commons.collections.TestComparator;
-
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 
-/**
- * TODO: document me.
- */
+/** TODO: document me. */
 public class ComparatorTest extends TestComparator {
   @Override
   public Comparator<Object> makeComparator() {
@@ -40,13 +36,9 @@
   }
 }
 
-/**
- * List comparator for testing.
- */
+/** List comparator for testing. */
 class DummyComparator implements Comparator<Object> {
-  /**
-   * Compares returns reverse hash order.
-   */
+  /** Compares returns reverse hash order. */
   @Override
   public int compare(Object arg0, Object arg1) {
     int a = arg0.hashCode();
@@ -61,4 +53,4 @@
     }
     return accum;
   }
-}
\ No newline at end of file
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/DefaultMapEntry.java b/user/test/com/google/gwt/emultest/java/util/DefaultMapEntry.java
new file mode 100644
index 0000000..96a3717
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/DefaultMapEntry.java
@@ -0,0 +1,116 @@
+// 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.Map;
+
+/** A default implementation of {@link java.util.Map.Entry} */
+@SuppressWarnings("rawtypes")
+class DefaultMapEntry implements Map.Entry {
+
+  private Object key;
+  private Object value;
+
+  /** Constructs a new <Code>DefaultMapEntry</Code> with a null key and null value. */
+  public DefaultMapEntry() {}
+
+  /**
+   * Constructs a new <Code>DefaultMapEntry</Code> with the given key and given value.
+   *
+   * @param key the key for the entry, may be null
+   * @param value the value for the entyr, may be null
+   */
+  public DefaultMapEntry(Object key, Object value) {
+    this.key = key;
+    this.value = value;
+  }
+
+  /** Implemented per API documentation of {@link java.util.Map.Entry#equals(Object)} */
+  @Override
+  public boolean equals(Object o) {
+    if (o == null) {
+      return false;
+    }
+    if (o == this) {
+      return true;
+    }
+
+    if (!(o instanceof Map.Entry)) {
+      return false;
+    }
+    Map.Entry e2 = (Map.Entry) o;
+    return ((getKey() == null ? e2.getKey() == null : getKey().equals(e2.getKey()))
+        && (getValue() == null ? e2.getValue() == null : getValue().equals(e2.getValue())));
+  }
+
+  /** Implemented per API documentation of {@link java.util.Map.Entry#hashCode()} */
+  @Override
+  public int hashCode() {
+    return ((getKey() == null ? 0 : getKey().hashCode())
+        ^ (getValue() == null ? 0 : getValue().hashCode()));
+  }
+
+  // Map.Entry interface
+  // -------------------------------------------------------------------------
+
+  /**
+   * Returns the key.
+   *
+   * @return the key
+   */
+  @Override
+  public Object getKey() {
+    return key;
+  }
+
+  /**
+   * Returns the value.
+   *
+   * @return the value
+   */
+  @Override
+  public Object getValue() {
+    return value;
+  }
+
+  // Properties
+  // -------------------------------------------------------------------------
+
+  /**
+   * Sets the key. This method does not modify any map.
+   *
+   * @param key the new key
+   */
+  public void setKey(Object key) {
+    this.key = key;
+  }
+
+  /**
+   * Note that this method only sets the local reference inside this object and does not modify the
+   * original Map.
+   *
+   * @return the old value of the value
+   * @param value the new value
+   */
+  @Override
+  public Object setValue(Object value) {
+    Object previous = this.value;
+    this.value = value;
+    return previous;
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/HashMapTest.java b/user/test/com/google/gwt/emultest/java/util/HashMapTest.java
index 466aea8..d47398c 100644
--- a/user/test/com/google/gwt/emultest/java/util/HashMapTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/HashMapTest.java
@@ -15,8 +15,6 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import org.apache.commons.collections.TestMap;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -27,9 +25,7 @@
 import java.util.NoSuchElementException;
 import java.util.Set;
 
-/**
- * Tests <code>HashMap</code>.
- */
+/** Tests <code>HashMap</code>. */
 public class HashMapTest extends TestMap {
   private static final int CAPACITY_16 = 16;
   private static final int CAPACITY_NEG_ONE_HALF = -1;
@@ -58,12 +54,13 @@
   private static final float LOAD_FACTOR_ONE_HALF = 0.5F;
   private static final float LOAD_FACTOR_ONE_TENTH = 0.1F;
   private static final float LOAD_FACTOR_ZERO = 0.0F;
-  private static final Object ODD_ZERO_KEY = new Object() {
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-  };
+  private static final Object ODD_ZERO_KEY =
+      new Object() {
+        @Override
+        public int hashCode() {
+          return 0;
+        }
+      };
   private static final String ODD_ZERO_VALUE = "odd zero";
   private static final int SIZE_ONE = 1;
   private static final int SIZE_THREE = 3;
@@ -77,13 +74,10 @@
   private static final String VALUE_4 = "val4";
   private static final String VALUE_TEST_CONTAINS_DOES_NOT_EXIST = "does not exist";
   private static final Integer VALUE_TEST_CONTAINS_KEY = new Integer(5);
-  private static final String VALUE_TEST_ENTRY_SET_1 = KEY_TEST_ENTRY_SET
-      + " - value1";
-  private static final String VALUE_TEST_ENTRY_SET_2 = KEY_TEST_ENTRY_SET
-      + " - value2";
+  private static final String VALUE_TEST_ENTRY_SET_1 = KEY_TEST_ENTRY_SET + " - value1";
+  private static final String VALUE_TEST_ENTRY_SET_2 = KEY_TEST_ENTRY_SET + " - value2";
   private static final String VALUE_TEST_GET = KEY_TEST_GET + " - Value";
-  private static final String VALUE_TEST_KEY_SET = KEY_TEST_KEY_SET
-      + " - value";
+  private static final String VALUE_TEST_KEY_SET = KEY_TEST_KEY_SET + " - value";
   private static final String VALUE_TEST_PUT_1 = KEY_TEST_PUT + " - value 1";
   private static final String VALUE_TEST_PUT_2 = KEY_TEST_PUT + " - value 2";
   private static final String VALUE_TEST_REMOVE = KEY_TEST_REMOVE + " - value";
@@ -215,11 +209,10 @@
     HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
     checkEmptyHashMapAssumptions(hashMap);
 
-    assertFalse("check contains of empty map",
-        hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
+    assertFalse("check contains of empty map", hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
     hashMap.put(KEY_TEST_CONTAINS_VALUE, VALUE_TEST_CONTAINS_KEY);
-    assertTrue("check contains of map with element",
-        hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
+    assertTrue(
+        "check contains of map with element", hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
     assertFalse(
         "check contains of map other element",
         hashMap.containsValue(
@@ -604,9 +597,7 @@
     assertEquals(VALUE_TEST_PUT_1, hashMap.put(null, VALUE_TEST_PUT_2));
   }
 
-  /**
-   * Test method for 'java.util.HashMap.putAll(Map)'.
-   */
+  /** Test method for 'java.util.HashMap.putAll(Map)'. */
   public void testPutAll() {
     HashMap<String, String> srcMap = new HashMap<String, String>();
     checkEmptyHashMapAssumptions(srcMap);
@@ -669,9 +660,7 @@
     dstMap.putAll(dstMap);
   }
 
-  /**
-   * Test method for 'java.util.HashMap.remove(Object)'.
-   */
+  /** Test method for 'java.util.HashMap.remove(Object)'. */
   public void testRemove() {
     HashMap<String, String> hashMap = new HashMap<String, String>();
     checkEmptyHashMapAssumptions(hashMap);
@@ -685,9 +674,7 @@
     assertNull(hashMap.remove(KEY_TEST_REMOVE));
   }
 
-  /**
-   * Test method for 'java.util.HashMap.size()'.
-   */
+  /** Test method for 'java.util.HashMap.size()'. */
   public void testSize() {
     HashMap<String, String> hashMap = new HashMap<String, String>();
     checkEmptyHashMapAssumptions(hashMap);
@@ -722,9 +709,7 @@
     assertEquals(SIZE_ZERO, hashMap.size());
   }
 
-  /**
-   * Test method for 'java.util.AbstractMap.toString()'.
-   */
+  /** Test method for 'java.util.AbstractMap.toString()'. */
   public void testToString() {
     HashMap<String, String> hashMap = new HashMap<String, String>();
     checkEmptyHashMapAssumptions(hashMap);
@@ -733,9 +718,7 @@
     assertTrue(entryString.equals(hashMap.toString()));
   }
 
-  /**
-   * Test method for 'java.util.AbstractMap.values()'.
-   */
+  /** Test method for 'java.util.AbstractMap.values()'. */
   public void testValues() {
     HashMap<String, String> hashMap = new HashMap<String, String>();
     checkEmptyHashMapAssumptions(hashMap);
diff --git a/user/test/com/google/gwt/emultest/java/util/HashSetTest.java b/user/test/com/google/gwt/emultest/java/util/HashSetTest.java
index ff45396..8defe14 100644
--- a/user/test/com/google/gwt/emultest/java/util/HashSetTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/HashSetTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2007 Google Inc.
- * 
+ *
  * 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
@@ -15,16 +15,12 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import org.apache.commons.collections.TestSet;
-
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-/**
- * TODO: document me.
- */
+/** Tests <code>HashSet</code>. */
 public class HashSetTest extends TestSet {
 
   public HashSetTest() {
@@ -54,5 +50,4 @@
   public Object makeObject() {
     return new HashSet();
   }
-
 }
diff --git a/user/test/com/google/gwt/emultest/java/util/IdentityHashMapTest.java b/user/test/com/google/gwt/emultest/java/util/IdentityHashMapTest.java
index 3cf9476..d4957bb 100644
--- a/user/test/com/google/gwt/emultest/java/util/IdentityHashMapTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/IdentityHashMapTest.java
@@ -24,17 +24,14 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import org.apache.commons.collections.TestMap;
 
-/**
- * Tests <code>IdentityHashMap</code>.
- */
+/** Tests <code>IdentityHashMap</code>. */
 @SuppressWarnings({"unchecked", "rawtypes"})
 public class IdentityHashMapTest extends TestMap {
 
   /**
-   * A class that is equal to all other instances of itself; used to ensure that
-   * identity rather than equality is being checked.
+   * A class that is equal to all other instances of itself; used to ensure that identity rather
+   * than equality is being checked.
    */
   private static class Foo {
     @Override
@@ -69,12 +66,13 @@
   private static final String KEY_TEST_KEY_SET = "testKeySet";
   private static final String KEY_TEST_PUT = "testPut";
   private static final String KEY_TEST_REMOVE = "testRemove";
-  private static final Object ODD_ZERO_KEY = new Object() {
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-  };
+  private static final Object ODD_ZERO_KEY =
+      new Object() {
+        @Override
+        public int hashCode() {
+          return 0;
+        }
+      };
   private static final String ODD_ZERO_VALUE = "odd zero";
   private static final int SIZE_ONE = 1;
   private static final int SIZE_THREE = 3;
@@ -88,13 +86,10 @@
   private static final String VALUE_4 = "val4";
   private static final String VALUE_TEST_CONTAINS_DOES_NOT_EXIST = "does not exist";
   private static final Integer VALUE_TEST_CONTAINS_KEY = new Integer(5);
-  private static final String VALUE_TEST_ENTRY_SET_1 = KEY_TEST_ENTRY_SET
-      + " - value1";
-  private static final String VALUE_TEST_ENTRY_SET_2 = KEY_TEST_ENTRY_SET
-      + " - value2";
+  private static final String VALUE_TEST_ENTRY_SET_1 = KEY_TEST_ENTRY_SET + " - value1";
+  private static final String VALUE_TEST_ENTRY_SET_2 = KEY_TEST_ENTRY_SET + " - value2";
   private static final String VALUE_TEST_GET = KEY_TEST_GET + " - Value";
-  private static final String VALUE_TEST_KEY_SET = KEY_TEST_KEY_SET
-      + " - value";
+  private static final String VALUE_TEST_KEY_SET = KEY_TEST_KEY_SET + " - value";
   private static final String VALUE_TEST_PUT_1 = KEY_TEST_PUT + " - value 1";
   private static final String VALUE_TEST_PUT_2 = KEY_TEST_PUT + " - value 2";
   private static final String VALUE_TEST_REMOVE = KEY_TEST_REMOVE + " - value";
@@ -217,12 +212,12 @@
     IdentityHashMap hashMap = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap);
 
-    assertFalse("check contains of empty map",
-        hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
+    assertFalse("check contains of empty map", hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
     hashMap.put(KEY_TEST_CONTAINS_VALUE, VALUE_TEST_CONTAINS_KEY);
-    assertTrue("check contains of map with element",
-        hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
-    assertFalse("check contains of map other element",
+    assertTrue(
+        "check contains of map with element", hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
+    assertFalse(
+        "check contains of map other element",
         hashMap.containsValue(VALUE_TEST_CONTAINS_DOES_NOT_EXIST));
 
     if (useNullValue()) {
@@ -453,10 +448,7 @@
     assertTrue(keyColl.contains(INTEGER_3));
   }
 
-  /**
-   * Test that the implementation differs from a standard map in demanding
-   * identity.
-   */
+  /** Test that the implementation differs from a standard map in demanding identity. */
   public void testIdentity() {
     IdentityHashMap hashMap = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap);
@@ -471,10 +463,7 @@
     assertNull(hashMap.get(foo2));
   }
 
-  /**
-   * Test that the implementation differs from a standard map in demanding
-   * identity.
-   */
+  /** Test that the implementation differs from a standard map in demanding identity. */
   public void testIdentityBasedEquality() {
     IdentityHashMap hashMap1 = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap1);
@@ -487,10 +476,7 @@
     assertFalse(hashMap1.equals(hashMap2));
   }
 
-  /**
-   * Test that the implementation differs from a standard map in demanding
-   * identity.
-   */
+  /** Test that the implementation differs from a standard map in demanding identity. */
   public void testIdentityBasedHashCode() {
     IdentityHashMap hashMap1 = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap1);
@@ -585,9 +571,7 @@
     assertEquals(VALUE_TEST_PUT_1, hashMap.put(null, VALUE_TEST_PUT_2));
   }
 
-  /**
-   * Test method for 'java.util.IdentityHashMap.putAll(Map)'.
-   */
+  /** Test method for 'java.util.IdentityHashMap.putAll(Map)'. */
   public void testPutAll() {
     IdentityHashMap srcMap = new IdentityHashMap();
     checkEmptyHashMapAssumptions(srcMap);
@@ -650,9 +634,7 @@
     dstMap.putAll(dstMap);
   }
 
-  /**
-   * Test method for 'java.util.IdentityHashMap.remove(Object)'.
-   */
+  /** Test method for 'java.util.IdentityHashMap.remove(Object)'. */
   public void testRemove() {
     IdentityHashMap hashMap = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap);
@@ -666,9 +648,7 @@
     assertNull(hashMap.remove(KEY_TEST_REMOVE));
   }
 
-  /**
-   * Test method for 'java.util.IdentityHashMap.size()'.
-   */
+  /** Test method for 'java.util.IdentityHashMap.size()'. */
   public void testSize() {
     IdentityHashMap hashMap = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap);
@@ -703,9 +683,7 @@
     assertEquals(SIZE_ZERO, hashMap.size());
   }
 
-  /**
-   * Test method for 'java.util.AbstractMap.toString()'.
-   */
+  /** Test method for 'java.util.AbstractMap.toString()'. */
   public void testToString() {
     IdentityHashMap hashMap = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap);
@@ -714,9 +692,7 @@
     assertTrue(entryString.equals(hashMap.toString()));
   }
 
-  /**
-   * Test method for 'java.util.AbstractMap.values()'.
-   */
+  /** Test method for 'java.util.AbstractMap.values()'. */
   public void testValues() {
     IdentityHashMap hashMap = new IdentityHashMap();
     checkEmptyHashMapAssumptions(hashMap);
diff --git a/user/test/com/google/gwt/emultest/java/util/LinkedHashMapTest.java b/user/test/com/google/gwt/emultest/java/util/LinkedHashMapTest.java
index 972ea8b..e6a11a2 100644
--- a/user/test/com/google/gwt/emultest/java/util/LinkedHashMapTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/LinkedHashMapTest.java
@@ -16,9 +16,6 @@
 package com.google.gwt.emultest.java.util;
 
 import com.google.gwt.testing.TestUtils;
-
-import org.apache.commons.collections.TestMap;
-
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -27,9 +24,7 @@
 import java.util.Map.Entry;
 import java.util.Set;
 
-/**
- * Tests <code>LinkedHashMap</code>.
- */
+/** Tests <code>LinkedHashMap</code>. */
 public class LinkedHashMapTest extends TestMap {
   // should be a method-level class, however to avoid serialization warning made
   // static instead.
@@ -84,12 +79,13 @@
   private static final float LOAD_FACTOR_ONE_HALF = 0.5F;
   private static final float LOAD_FACTOR_ONE_TENTH = 0.1F;
   private static final float LOAD_FACTOR_ZERO = 0.0F;
-  private static final Object ODD_ZERO_KEY = new Object() {
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-  };
+  private static final Object ODD_ZERO_KEY =
+      new Object() {
+        @Override
+        public int hashCode() {
+          return 0;
+        }
+      };
   private static final String ODD_ZERO_VALUE = "odd zero";
   private static final int SIZE_ONE = 1;
   private static final int SIZE_THREE = 3;
@@ -103,13 +99,10 @@
   private static final String VALUE_4 = "val4";
   private static final String VALUE_TEST_CONTAINS_DOES_NOT_EXIST = "does not exist";
   private static final Integer VALUE_TEST_CONTAINS_KEY = new Integer(5);
-  private static final String VALUE_TEST_ENTRY_SET_1 = KEY_TEST_ENTRY_SET
-      + " - value1";
-  private static final String VALUE_TEST_ENTRY_SET_2 = KEY_TEST_ENTRY_SET
-      + " - value2";
+  private static final String VALUE_TEST_ENTRY_SET_1 = KEY_TEST_ENTRY_SET + " - value1";
+  private static final String VALUE_TEST_ENTRY_SET_2 = KEY_TEST_ENTRY_SET + " - value2";
   private static final String VALUE_TEST_GET = KEY_TEST_GET + " - Value";
-  private static final String VALUE_TEST_KEY_SET = KEY_TEST_KEY_SET
-      + " - value";
+  private static final String VALUE_TEST_KEY_SET = KEY_TEST_KEY_SET + " - value";
   private static final String VALUE_TEST_PUT_1 = KEY_TEST_PUT + " - value 1";
   private static final String VALUE_TEST_PUT_2 = KEY_TEST_PUT + " - value 2";
   private static final String VALUE_TEST_REMOVE = KEY_TEST_REMOVE + " - value";
@@ -232,11 +225,10 @@
     LinkedHashMap<String, Integer> hashMap = new LinkedHashMap<String, Integer>();
     checkEmptyLinkedHashMapAssumptions(hashMap);
 
-    assertFalse("check contains of empty map",
-        hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
+    assertFalse("check contains of empty map", hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
     hashMap.put(KEY_TEST_CONTAINS_VALUE, VALUE_TEST_CONTAINS_KEY);
-    assertTrue("check contains of map with element",
-        hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
+    assertTrue(
+        "check contains of map with element", hashMap.containsValue(VALUE_TEST_CONTAINS_KEY));
     assertFalse(
         "check contains of map other element",
         hashMap.containsValue(
@@ -453,8 +445,8 @@
    */
   public void testLinkedHashMapIntFloat() {
 
-    LinkedHashMap<String, String> hashMap = new LinkedHashMap<String, String>(CAPACITY_16,
-        LOAD_FACTOR_ONE_HALF);
+    LinkedHashMap<String, String> hashMap =
+        new LinkedHashMap<String, String>(CAPACITY_16, LOAD_FACTOR_ONE_HALF);
     checkEmptyLinkedHashMapAssumptions(hashMap);
 
     // TODO(mmendez): how do we verify capacity and load factor?
@@ -520,8 +512,7 @@
   }
 
   public void testLRU() {
-    LinkedHashMap<String, String> m = new LinkedHashMap<String, String>(10,
-        .5f, true);
+    LinkedHashMap<String, String> m = new LinkedHashMap<String, String>(10, .5f, true);
     m.put("A", "A");
     m.put("B", "B");
     m.put("C", "C");
@@ -553,9 +544,7 @@
     assertEquals(VALUE_TEST_PUT_1, hashMap.put(null, VALUE_TEST_PUT_2));
   }
 
-  /**
-   * Test method for 'java.util.LinkedHashMap.putAll(Map)'.
-   */
+  /** Test method for 'java.util.LinkedHashMap.putAll(Map)'. */
   public void testPutAll() {
     LinkedHashMap<String, String> srcMap = new LinkedHashMap<String, String>();
     checkEmptyLinkedHashMapAssumptions(srcMap);
@@ -618,9 +607,7 @@
     dstMap.putAll(dstMap);
   }
 
-  /**
-   * Test method for 'java.util.LinkedHashMap.remove(Object)'.
-   */
+  /** Test method for 'java.util.LinkedHashMap.remove(Object)'. */
   public void testRemove() {
     LinkedHashMap<String, String> hashMap = new LinkedHashMap<String, String>();
     checkEmptyLinkedHashMapAssumptions(hashMap);
@@ -674,9 +661,7 @@
     assertEquals("New-C", entries.next().getValue());
   }
 
-  /**
-   * Test method for 'java.util.LinkedHashMap.size()'.
-   */
+  /** Test method for 'java.util.LinkedHashMap.size()'. */
   public void testSize() {
     LinkedHashMap<String, String> hashMap = new LinkedHashMap<String, String>();
     checkEmptyLinkedHashMapAssumptions(hashMap);
@@ -711,9 +696,7 @@
     assertEquals(SIZE_ZERO, hashMap.size());
   }
 
-  /**
-   * Test method for 'java.util.AbstractMap.toString()'.
-   */
+  /** Test method for 'java.util.AbstractMap.toString()'. */
   public void testToString() {
     LinkedHashMap<String, String> hashMap = new LinkedHashMap<String, String>();
     checkEmptyLinkedHashMapAssumptions(hashMap);
@@ -722,9 +705,7 @@
     assertTrue(entryString.equals(hashMap.toString()));
   }
 
-  /**
-   * Test method for 'java.util.AbstractMap.values()'.
-   */
+  /** Test method for 'java.util.AbstractMap.values()'. */
   public void testValues() {
     LinkedHashMap<String, String> hashMap = new LinkedHashMap<String, String>();
     checkEmptyLinkedHashMapAssumptions(hashMap);
@@ -748,10 +729,9 @@
   }
 
   /**
-   * This method exists because java 1.5 no longer has
-   * LinkedHashMap(LinkedHashMap), replacing it with LinkedHashMap(Map<? extends
-   * K, ? extends V> m). Nevertheless, we want to use it in Production Mode to
-   * test that Production Mode function.
+   * This method exists because java 1.5 no longer has LinkedHashMap(LinkedHashMap), replacing it
+   * with LinkedHashMap(Map<? extends K, ? extends V> m). Nevertheless, we want to use it in
+   * Production Mode to test that Production Mode function.
    *
    * @param hashMap the LinkedHashMap to be copied
    * @return the copy
diff --git a/user/test/com/google/gwt/emultest/java/util/LinkedHashSetTest.java b/user/test/com/google/gwt/emultest/java/util/LinkedHashSetTest.java
index 5de7cd2..db6d148 100644
--- a/user/test/com/google/gwt/emultest/java/util/LinkedHashSetTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/LinkedHashSetTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2013 Google Inc.
- * 
+ *
  * 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
@@ -15,14 +15,10 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import org.apache.commons.collections.TestSet;
-
 import java.util.LinkedHashSet;
 import java.util.Set;
 
-/**
- * Tests <code>LinkedHashSet</code>.
- */
+/** Tests <code>LinkedHashSet</code>. */
 public class LinkedHashSetTest extends TestSet {
 
   private static final String VALUE_1 = "val1";
@@ -32,7 +28,7 @@
 
   /**
    * Check the state of a newly constructed, empty LinkedHashSet.
-   * 
+   *
    * @param hashSet
    */
   private static void checkEmptyLinkedHashSetAssumptions(LinkedHashSet<?> hashSet) {
diff --git a/user/test/com/google/gwt/emultest/java/util/ListTestBase.java b/user/test/com/google/gwt/emultest/java/util/ListTestBase.java
index 94787d9..90ba0d3 100644
--- a/user/test/com/google/gwt/emultest/java/util/ListTestBase.java
+++ b/user/test/com/google/gwt/emultest/java/util/ListTestBase.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 Google Inc.
- * 
+ *
  * 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
@@ -15,8 +15,6 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import org.apache.commons.collections.TestArrayList;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -24,32 +22,32 @@
 import java.util.ListIterator;
 
 /**
- * Tests List, and, by extension AbstractList. Uses inheritance to inherit all
- * of Apache's TestList and TestCollection.
+ * Tests List, and, by extension AbstractList. Uses inheritance to inherit all of Apache's TestList
+ * and TestCollection.
  */
 @SuppressWarnings("unchecked")
 public abstract class ListTestBase extends TestArrayList {
 
-  private static volatile boolean NO_OPTIMIZE_FALSE = false;
+  private static final boolean NO_OPTIMIZE_FALSE = false;
 
   public void testAddAll() {
     List<Integer> list = makeEmptyList();
     list.addAll(Arrays.asList(1, 2, 3, 4));
     list.addAll(2, Arrays.asList(21, 22));
 
-    checkListSizeAndContent(list, 1, 2, 21, 22, 3 ,4);
+    checkListSizeAndContent(list, 1, 2, 21, 22, 3, 4);
 
     list = makeEmptyList();
     list.addAll(Arrays.asList(1, 2, 3, 4));
     list.addAll(0, Arrays.asList(21, 22));
 
-    checkListSizeAndContent(list, 21, 22, 1, 2, 3 ,4);
+    checkListSizeAndContent(list, 21, 22, 1, 2, 3, 4);
 
     list = makeEmptyList();
     list.addAll(Arrays.asList(1, 2, 3, 4));
     list.addAll(4, Arrays.asList(21, 22));
 
-    checkListSizeAndContent(list, 1, 2, 3 ,4, 21, 22);
+    checkListSizeAndContent(list, 1, 2, 3, 4, 21, 22);
   }
 
   public void testAddAllReturnValue() {
@@ -237,9 +235,7 @@
     }
   }
 
-  /**
-   * Test add() method for list returned by List<E>.subList() method.
-   */
+  /** Test add() method for list returned by List<E>.subList() method. */
   public void testSubListAdd() {
     List<Integer> baseList = createListWithContent(new int[] {1, 2, 3, 4, 5});
     List<Integer> sublist = baseList.subList(1, 3);
@@ -299,14 +295,14 @@
       fail("Expected IndexOutOfBoundsException");
     } catch (IndexOutOfBoundsException expected) {
     }
-    
+
     assertFalse(sublist.remove(Integer.valueOf(4)));
-    
+
     assertTrue(sublist.remove(Integer.valueOf(3)));
-    
+
     assertEquals(0, sublist.size());
     assertEquals(3, baseList.size());
-    
+
     sublist.add(6);
     checkListSizeAndContent(baseList, 1, 6, 4, 5);
   }
diff --git a/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java b/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java
index abed20f..5a9051e 100644
--- a/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java
@@ -15,8 +15,6 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import org.apache.commons.collections.TestCollection;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -25,9 +23,7 @@
 import java.util.PriorityQueue;
 import java.util.TreeSet;
 
-/**
- * Test PriorityQueue.
- */
+/** Test PriorityQueue. */
 public class PriorityQueueTest extends TestCollection {
 
   public void testAdd() {
@@ -35,6 +31,7 @@
 
     try {
       queue.add(null);
+      fail("Expected NullPointerException");
     } catch (NullPointerException expected) {
     }
 
@@ -140,12 +137,13 @@
     pq = new PriorityQueue<Integer>(11);
     assertNull(pq.comparator());
 
-    Comparator<Integer> comparator = new Comparator<Integer>() {
-      @Override
-      public int compare(Integer o1, Integer o2) {
-        return o1 - o2;
-      }
-    };
+    Comparator<Integer> comparator =
+        new Comparator<Integer>() {
+          @Override
+          public int compare(Integer o1, Integer o2) {
+            return o1 - o2;
+          }
+        };
     pq = new PriorityQueue<Integer>(11, comparator);
     assertEquals(comparator, pq.comparator());
 
@@ -243,9 +241,7 @@
     return pq;
   }
 
-  /**
-   * Null elements are prohibited in PriorityQueue.
-   */
+  /** Null elements are prohibited in PriorityQueue. */
   @Override
   protected Object[] getFullElements() {
     return new Integer[] {1, 2, 3, 4};
diff --git a/user/test/org/apache/commons/collections/TestArrayList.java b/user/test/com/google/gwt/emultest/java/util/TestArrayList.java
similarity index 63%
rename from user/test/org/apache/commons/collections/TestArrayList.java
rename to user/test/com/google/gwt/emultest/java/util/TestArrayList.java
index 32eb554..bfc919f 100644
--- a/user/test/org/apache/commons/collections/TestArrayList.java
+++ b/user/test/com/google/gwt/emultest/java/util/TestArrayList.java
@@ -1,3 +1,4 @@
+// CHECKSTYLE_OFF: Copyrighted to ASF
 /*
  * Copyright 1999-2004 The Apache Software Foundation
  *
@@ -13,36 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+// CHECKSTYLE_ON
 // MODIFIED BY GOOGLE
-package org.apache.commons.collections;
+package com.google.gwt.emultest.java.util;
 
 import java.util.List;
 
-/**
- * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
- * @version $Id: TestArrayList.java,v 1.5.2.1 2004/05/22 12:14:05 scolebourne Exp $
- */
 @SuppressWarnings({"unchecked", "rawtypes"})
-public abstract class TestArrayList extends TestList
-{ 
-  
- 
-    // GOOGLE
-    protected List list = makeEmptyList();
+abstract class TestArrayList extends TestList {
 
+  // GOOGLE
+  protected List list = makeEmptyList();
 
-    public void testNewArrayList()
-    {
-         assertTrue("New list is empty", list.isEmpty());
+  public void testNewArrayList() {
+    assertTrue("New list is empty", list.isEmpty());
     assertEquals("New list has size zero", 0, list.size());
-    }
+  }
 
-    public void testSearch()
-    {
-        list.add("First Item");
-        list.add("Last Item");
+  public void testSearch() {
+    list.add("First Item");
+    list.add("Last Item");
     assertEquals("First item is 'First Item'", "First Item", list.get(0));
     assertEquals("Last Item is 'Last Item'", "Last Item", list.get(1));
-    }
-
+  }
 }
diff --git a/user/test/com/google/gwt/emultest/java/util/TestCollection.java b/user/test/com/google/gwt/emultest/java/util/TestCollection.java
new file mode 100644
index 0000000..5fbf556
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TestCollection.java
@@ -0,0 +1,961 @@
+// 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"
+    };
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/TestComparator.java b/user/test/com/google/gwt/emultest/java/util/TestComparator.java
new file mode 100644
index 0000000..8c04bb8
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TestComparator.java
@@ -0,0 +1,121 @@
+// 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.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+@SuppressWarnings({"unchecked", "rawtypes"})
+abstract class TestComparator extends TestObject {
+
+  public abstract Comparator makeComparator();
+
+  public abstract List getComparableObjectsOrdered();
+
+  @Override
+  public Object makeObject() {
+    return makeComparator();
+  }
+
+  /**
+   * There were no Comparators in version 1.x.
+   *
+   * @return 2
+   */
+  @Override
+  public int getCompatibilityVersion() {
+    return 2;
+  }
+
+  public void reverseObjects(List list) {
+    Collections.reverse(list);
+  }
+
+  /**
+   * Sort object according to the given Comparator.
+   *
+   * @param list List to sort
+   * @param comparator sorting comparator
+   */
+  public void sortObjects(List list, Comparator comparator) {
+
+    Collections.sort(list, comparator);
+  }
+
+  @Override
+  public boolean supportsEmptyCollections() {
+    return false;
+  }
+
+  @Override
+  public boolean supportsFullCollections() {
+    return false;
+  }
+
+  public void testEmptyListSort() {
+    List list = new ArrayList();
+    sortObjects(list, makeComparator());
+
+    List list2 = new ArrayList();
+
+    assertTrue("Comparator cannot sort empty lists", list2.equals(list));
+  }
+
+  public void testReverseListSort() {
+    Comparator comparator = makeComparator();
+
+    List randomList = getComparableObjectsOrdered();
+    reverseObjects(randomList);
+    sortObjects(randomList, comparator);
+
+    List orderedList = getComparableObjectsOrdered();
+
+    assertTrue("Comparator did not reorder the List correctly", orderedList.equals(randomList));
+  }
+
+  public String getCanonicalComparatorName(Object object) {
+    StringBuilder retval = new StringBuilder();
+    retval.append("data/test/");
+    String colName = object.getClass().getName();
+    colName = colName.substring(colName.lastIndexOf(".") + 1);
+    retval.append(colName);
+    retval.append(".version");
+    retval.append(getCompatibilityVersion());
+    retval.append(".obj");
+    return retval.toString();
+  }
+
+  /** Compare the current serialized form of the Comparator against the canonical version in CVS. */
+  public void testComparatorCompatibility() {
+    Comparator comparator = null;
+
+    // make sure the canonical form produces the ordering we currently
+    // expect
+    List randomList = getComparableObjectsOrdered();
+    reverseObjects(randomList);
+    sortObjects(randomList, comparator);
+
+    List orderedList = getComparableObjectsOrdered();
+
+    assertTrue(
+        "Comparator did not reorder the List correctly:" + randomList,
+        orderedList.equals(randomList));
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/TestIterator.java b/user/test/com/google/gwt/emultest/java/util/TestIterator.java
new file mode 100644
index 0000000..49df5ea
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TestIterator.java
@@ -0,0 +1,102 @@
+// 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.Iterator;
+import java.util.NoSuchElementException;
+
+/** Base class for testing Iterator interface */
+@SuppressWarnings("rawtypes")
+abstract class TestIterator extends TestObject {
+
+  public abstract Iterator makeEmptyIterator();
+
+  public abstract Iterator makeFullIterator();
+
+  /**
+   * Whether or not we are testing an iterator that can be empty. Default is true.
+   *
+   * @return true if Iterators can be empty
+   */
+  public boolean supportsEmptyIterator() {
+    return true;
+  }
+
+  /**
+   * Whether or not we are testing an iterator that can contain elements. Default is true.
+   *
+   * @return true if Iterators can be empty
+   */
+  public boolean supportsFullIterator() {
+    return true;
+  }
+
+  /**
+   * Whether or not we are testing an iterator that supports remove. Default is true.
+   *
+   * @return true if Iterators can remove elements
+   */
+  public boolean supportsRemove() {
+    return true;
+  }
+
+  /** Should throw a NoSuchElementException. */
+  public void testEmptyIterator() {
+    if (!supportsEmptyIterator()) {
+      return;
+    }
+
+    Iterator iter = makeEmptyIterator();
+    assertTrue("hasNext() should return false for empty iterators", !iter.hasNext());
+    try {
+      iter.next();
+      fail("NoSuchElementException must be thrown when Iterator is exhausted");
+    } catch (NoSuchElementException e) {
+    }
+  }
+
+  /**
+   * NoSuchElementException (or any other exception) should not be thrown for the first element.
+   * NoSuchElementException must be thrown when hasNext() returns false
+   */
+  public void testFullIterator() {
+    if (!supportsFullIterator()) {
+      return;
+    }
+
+    Iterator iter = makeFullIterator();
+
+    assertTrue("hasNext() should return true for at least one element", iter.hasNext());
+
+    try {
+      iter.next();
+    } catch (NoSuchElementException e) {
+      fail("Full iterators must have at least one element");
+    }
+
+    while (iter.hasNext()) {
+      iter.next();
+    }
+
+    try {
+      iter.next();
+      fail("NoSuchElementException must be thrown when Iterator is exhausted");
+    } catch (NoSuchElementException e) {
+    }
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/TestList.java b/user/test/com/google/gwt/emultest/java/util/TestList.java
new file mode 100644
index 0000000..9613a8f
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TestList.java
@@ -0,0 +1,627 @@
+// 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.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests base {@link java.util.List} methods and contracts.
+ *
+ * <p>To use, simply extend this class, and implement the {@link #makeList} method.
+ *
+ * <p>If your {@link List} fails one of these tests by design, you may still use this base set of
+ * cases. Simply override the test case (method) your {@link List} fails.
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+abstract class TestList extends TestCollection {
+
+  /**
+   * Return a new, empty {@link List} to be used for testing.
+   *
+   * @return an empty list for testing.
+   */
+  protected abstract List makeEmptyList();
+
+  /**
+   * Return a new, full {@link List} to be used for testing.
+   *
+   * @return a full list for testing
+   */
+  protected List makeFullList() {
+    // only works if list supports optional "addAll(Collection)"
+    List list = makeEmptyList();
+    list.addAll(Arrays.asList(getFullElements()));
+    return list;
+  }
+
+  /**
+   * Returns {@link makeEmptyList()}.
+   *
+   * @return an empty list to be used for testing
+   */
+  @Override
+  protected final Collection makeCollection() {
+    return makeEmptyList();
+  }
+
+  /**
+   * Returns {@link makeFullList()}.
+   *
+   * @return a full list to be used for testing
+   */
+  @Override
+  protected final Collection makeFullCollection() {
+    return makeFullList();
+  }
+
+  /**
+   * Whether or not we are testing an iterator that can be empty. Default is true.
+   *
+   * @return true if Iterators can be empty
+   */
+  public boolean supportsEmptyIterator() {
+    return true;
+  }
+
+  /**
+   * Whether or not we are testing an list that allows element set. Default is true.
+   *
+   * @return true if Lists support element set
+   */
+  public boolean isSetSupported() {
+    return true;
+  }
+
+  /**
+   * Returns the {@link collection} field cast to a {@link List}.
+   *
+   * @return the collection field as a List
+   */
+  protected List getList() {
+    return (List) collection;
+  }
+
+  /**
+   * Returns the {@link confirmed} field cast to a {@link List}.
+   *
+   * @return the confirmed field as a List
+   */
+  protected List getConfirmedList() {
+    return (List) confirmed;
+  }
+
+  public class TestListIterator extends AbstractTestListIterator {
+
+    @Override
+    public Object addSetValue() {
+      return TestList.this.getOtherElements()[0];
+    }
+
+    @Override
+    public boolean supportsRemove() {
+      return TestList.this.isRemoveSupported();
+    }
+
+    @Override
+    public boolean supportsAdd() {
+      return TestList.this.isAddSupported();
+    }
+
+    @Override
+    public boolean supportsSet() {
+      return TestList.this.isSetSupported();
+    }
+
+    @Override
+    public ListIterator makeEmptyListIterator() {
+      resetEmpty();
+      return ((List) TestList.this.collection).listIterator();
+    }
+
+    @Override
+    public ListIterator makeFullListIterator() {
+      resetFull();
+      return ((List) TestList.this.collection).listIterator();
+    }
+
+    @Override
+    public Object makeObject() {
+      return ((List) TestList.this.collection).listIterator();
+    }
+  }
+
+  /** Tests the read-only bits of {@link List#listIterator()}. */
+  public void testListListIterator() {
+    resetFull();
+    forwardTest(getList().listIterator(), 0);
+    backwardTest(getList().listIterator(), 0);
+  }
+
+  /** Tests the read-only bits of {@link List#listIterator(int)}. */
+  public void testListListIteratorByIndex() {
+    resetFull();
+    try {
+      getList().listIterator(-1);
+    } catch (IndexOutOfBoundsException ex) {
+    }
+    resetFull();
+    try {
+      getList().listIterator(getList().size() + 1);
+    } catch (IndexOutOfBoundsException ex) {
+    }
+    resetFull();
+    for (int i = 0; i <= confirmed.size(); i++) {
+      forwardTest(getList().listIterator(i), i);
+      backwardTest(getList().listIterator(i), i);
+    }
+    resetFull();
+    for (int i = 0; i <= confirmed.size(); i++) {
+      backwardTest(getList().listIterator(i), i);
+    }
+  }
+
+  // -----------------------------------------------------------------------
+  /** Tests remove on list iterator is correct. */
+  public void testListListIteratorPreviousRemoveNext() {
+    if (!isRemoveSupported()) {
+      return;
+    }
+    resetFull();
+    if (collection.size() < 4) {
+      return;
+    }
+    ListIterator it = getList().listIterator();
+    Object zero = it.next();
+    Object one = it.next();
+    Object two = it.next();
+    Object two2 = it.previous();
+    Object one2 = it.previous();
+    assertEquals(one, one2);
+    assertEquals(two, two2);
+    assertEquals(zero, getList().get(0));
+    assertEquals(one, getList().get(1));
+    assertEquals(two, getList().get(2));
+
+    it.remove(); // removed element at index 1 (one)
+    assertEquals(zero, getList().get(0));
+    assertEquals(two, getList().get(1));
+    Object two3 = it.next(); // do next after remove
+    assertEquals(two, two3);
+    assertEquals(collection.size() > 2, it.hasNext());
+    assertTrue(it.hasPrevious());
+  }
+
+  /** Tests remove on list iterator is correct. */
+  public void testListListIteratorPreviousRemovePrevious() {
+    if (!isRemoveSupported()) {
+      return;
+    }
+    resetFull();
+    if (collection.size() < 4) {
+      return;
+    }
+    ListIterator it = getList().listIterator();
+    Object zero = it.next();
+    Object one = it.next();
+    Object two = it.next();
+    Object two2 = it.previous();
+    Object one2 = it.previous();
+    assertEquals(one, one2);
+    assertEquals(two, two2);
+    assertEquals(zero, getList().get(0));
+    assertEquals(one, getList().get(1));
+    assertEquals(two, getList().get(2));
+
+    it.remove(); // removed element at index 1 (one)
+    assertEquals(zero, getList().get(0));
+    assertEquals(two, getList().get(1));
+    Object zero3 = it.previous(); // do previous after remove
+    assertEquals(zero, zero3);
+    assertEquals(false, it.hasPrevious());
+    assertEquals(collection.size() > 2, it.hasNext());
+  }
+
+  /** Tests remove on list iterator is correct. */
+  public void testListListIteratorNextRemoveNext() {
+    if (!isRemoveSupported()) {
+      return;
+    }
+    resetFull();
+    if (collection.size() < 4) {
+      return;
+    }
+    ListIterator it = getList().listIterator();
+    Object zero = it.next();
+    Object one = it.next();
+    Object two = it.next();
+    assertEquals(zero, getList().get(0));
+    assertEquals(one, getList().get(1));
+    assertEquals(two, getList().get(2));
+    Object three = getList().get(3);
+
+    it.remove(); // removed element at index 2 (two)
+    assertEquals(zero, getList().get(0));
+    assertEquals(one, getList().get(1));
+    Object three2 = it.next(); // do next after remove
+    assertEquals(three, three2);
+    assertEquals(collection.size() > 3, it.hasNext());
+    assertEquals(true, it.hasPrevious());
+  }
+
+  /** Tests remove on list iterator is correct. */
+  public void testListListIteratorNextRemovePrevious() {
+    if (!isRemoveSupported()) {
+      return;
+    }
+    resetFull();
+    if (collection.size() < 4) {
+      return;
+    }
+    ListIterator it = getList().listIterator();
+    Object zero = it.next();
+    Object one = it.next();
+    Object two = it.next();
+    assertEquals(zero, getList().get(0));
+    assertEquals(one, getList().get(1));
+    assertEquals(two, getList().get(2));
+
+    it.remove(); // removed element at index 2 (two)
+    assertEquals(zero, getList().get(0));
+    assertEquals(one, getList().get(1));
+    Object one2 = it.previous(); // do previous after remove
+    assertEquals(one, one2);
+    assertEquals(true, it.hasNext());
+    assertEquals(true, it.hasPrevious());
+  }
+
+  // -----------------------------------------------------------------------
+  /**
+   * Traverses to the end of the given iterator.
+   *
+   * @param iter the iterator to traverse
+   * @param i the starting index
+   */
+  private void forwardTest(ListIterator iter, int i) {
+    List list = getList();
+    int max = getFullElements().length;
+
+    while (i < max) {
+      assertTrue("Iterator should have next", iter.hasNext());
+      assertEquals("Iterator.nextIndex should work", iter.nextIndex(), i);
+      assertEquals("Iterator.previousIndex should work", iter.previousIndex(), i - 1);
+      Object o = iter.next();
+      assertEquals("Iterator returned correct element f", list.get(i), o);
+      i++;
+    }
+
+    assertTrue("Iterator shouldn't have next", !iter.hasNext());
+    assertEquals("nextIndex should be size", iter.nextIndex(), max);
+    assertEquals("previousIndex should be size - 1", iter.previousIndex(), max - 1);
+
+    try {
+      iter.next();
+      fail("Exhausted iterator should raise NoSuchElement");
+    } catch (NoSuchElementException e) {
+      // expected
+    }
+  }
+
+  /**
+   * Traverses to the beginning of the given iterator.
+   *
+   * @param iter the iterator to traverse
+   * @param i the starting index
+   */
+  private void backwardTest(ListIterator iter, int i) {
+    List list = getList();
+
+    while (i > 0) {
+      assertTrue("Iterator should have previous, i:" + i, iter.hasPrevious());
+      assertEquals("Iterator.nextIndex should work, i:" + i, iter.nextIndex(), i);
+      assertEquals("Iterator.previousIndex should work, i:" + i, iter.previousIndex(), i - 1);
+      Object o = iter.previous();
+      assertEquals("Iterator returned correct element b", list.get(i - 1), o);
+      i--;
+    }
+
+    assertTrue("Iterator shouldn't have previous", !iter.hasPrevious());
+    int nextIndex = iter.nextIndex();
+    assertEquals("nextIndex should be 0, actual value: " + nextIndex, 0, nextIndex);
+    int prevIndex = iter.previousIndex();
+    assertEquals("previousIndex should be -1, actual value: " + prevIndex, -1, prevIndex);
+
+    try {
+      iter.previous();
+      fail("Exhausted iterator should raise NoSuchElement");
+    } catch (NoSuchElementException e) {
+      // expected
+    }
+  }
+
+  /** Tests the {@link ListIterator#add(Object)} method of the list iterator. */
+  public void testListIteratorAdd() {
+    if (!isAddSupported()) {
+      return;
+    }
+
+    resetEmpty();
+    List list1 = getList();
+    List list2 = getConfirmedList();
+
+    Object[] elements = getFullElements();
+    ListIterator iter1 = list1.listIterator();
+    ListIterator iter2 = list2.listIterator();
+
+    for (int i = 0; i < elements.length; i++) {
+      iter1.add(elements[i]);
+      iter2.add(elements[i]);
+      verify();
+    }
+
+    resetFull();
+    iter1 = getList().listIterator();
+    iter2 = getConfirmedList().listIterator();
+    for (int i = 0; i < elements.length; i++) {
+      iter1.next();
+      iter2.next();
+      iter1.add(elements[i]);
+      iter2.add(elements[i]);
+      verify();
+    }
+  }
+
+  /** Tests the {@link ListIterator#set(Object)} method of the list iterator. */
+  public void testListIteratorSet() {
+    if (!isSetSupported()) {
+      return;
+    }
+
+    Object[] elements = getFullElements();
+
+    resetFull();
+    ListIterator iter1 = getList().listIterator();
+    ListIterator iter2 = getConfirmedList().listIterator();
+    for (int i = 0; i < elements.length; i++) {
+      iter1.next();
+      iter2.next();
+      iter1.set(elements[i]);
+      iter2.set(elements[i]);
+      verify();
+    }
+  }
+
+  /** Tests {@link List#add(int,Object)}. */
+  public void testListAddByIndex() {
+    if (!isAddSupported()) {
+      return;
+    }
+
+    Object element = getOtherElements()[0];
+    int max = getFullElements().length;
+
+    for (int i = 0; i <= max; i++) {
+      resetFull();
+      ((List) collection).add(i, element);
+      ((List) confirmed).add(i, element);
+      verify();
+    }
+  }
+
+  /** Tests {@link List#equals(Object)}. */
+  public void testListEquals() {
+    resetEmpty();
+    List list = getList();
+    assertTrue("Empty lists should be equal", list.equals(confirmed));
+    verify();
+    assertTrue("Empty list should equal self", list.equals(list));
+    verify();
+
+    List list2 = Arrays.asList(getFullElements());
+    assertTrue("Empty list shouldn't equal full", !list.equals(list2));
+    verify();
+
+    list2 = Arrays.asList(getOtherElements());
+    assertTrue("Empty list shouldn't equal other", !list.equals(list2));
+    verify();
+
+    resetFull();
+    list = getList();
+    assertTrue("Full lists should be equal", list.equals(confirmed));
+    verify();
+    assertTrue("Full list should equal self", list.equals(list));
+    verify();
+
+    list2 = makeEmptyList();
+    assertTrue("Full list shouldn't equal empty", !list.equals(list2));
+    verify();
+
+    list2 = Arrays.asList(getOtherElements());
+    assertTrue("Full list shouldn't equal other", !list.equals(list2));
+    verify();
+
+    list2 = Arrays.asList(getFullElements());
+    Collections.reverse(list2);
+    assertTrue(
+        "Full list shouldn't equal full list with same elements" + " but different order",
+        !list.equals(list2));
+    verify();
+
+    assertTrue("List shouldn't equal String", !list.equals(""));
+    verify();
+
+    final List listForC = Arrays.asList(getFullElements());
+    Collection c =
+        new AbstractCollection() {
+          @Override
+          public int size() {
+            return listForC.size();
+          }
+
+          @Override
+          public Iterator iterator() {
+            return listForC.iterator();
+          }
+        };
+
+    assertTrue(
+        "List shouldn't equal nonlist with same elements " + " in same order", !list.equals(c));
+    verify();
+  }
+
+  /** Tests {@link List#hashCode()}. */
+  public void testListHashCode() {
+    resetEmpty();
+    int hash1 = collection.hashCode();
+    int hash2 = confirmed.hashCode();
+    assertEquals("Empty lists should have equal hashCodes", hash1, hash2);
+    verify();
+
+    resetFull();
+    hash1 = collection.hashCode();
+    hash2 = confirmed.hashCode();
+    assertEquals("Full lists should have equal hashCodes", hash1, hash2);
+    verify();
+  }
+
+  /** Tests {@link List#get(int)}. */
+  public void testListGetByIndex() {
+    resetFull();
+    List list = getList();
+    Object[] elements = getFullElements();
+    for (int i = 0; i < elements.length; i++) {
+      assertEquals("List should contain correct elements", elements[i], list.get(i));
+      verify();
+    }
+  }
+
+  /** Tests {@link List#indexOf()}. */
+  public void testListIndexOf() {
+    resetFull();
+    List list1 = getList();
+    List list2 = getConfirmedList();
+
+    Iterator iterator = list2.iterator();
+    while (iterator.hasNext()) {
+      Object element = iterator.next();
+      assertEquals(
+          "indexOf should return correct result", list1.indexOf(element), list2.indexOf(element));
+      verify();
+    }
+
+    Object[] other = getOtherElements();
+    for (int i = 0; i < other.length; i++) {
+      assertEquals("indexOf should return -1 for nonexistent element", -1, list1.indexOf(other[i]));
+      verify();
+    }
+  }
+
+  /** Tests {@link List#lastIndexOf()}. */
+  public void testListLastIndexOf() {
+    resetFull();
+    List list1 = getList();
+    List list2 = getConfirmedList();
+
+    Iterator iterator = list2.iterator();
+    while (iterator.hasNext()) {
+      Object element = iterator.next();
+      assertEquals(
+          "lastIndexOf should return correct result",
+          list1.lastIndexOf(element),
+          list2.lastIndexOf(element));
+      verify();
+    }
+
+    Object[] other = getOtherElements();
+    for (int i = 0; i < other.length; i++) {
+      assertEquals(
+          "lastIndexOf should return -1 for nonexistent " + "element",
+          -1,
+          list1.lastIndexOf(other[i]));
+      verify();
+    }
+  }
+
+  /** Tests {@link List#remove(int)}. */
+  public void testListRemoveByIndex() {
+    if (!isRemoveSupported()) {
+      return;
+    }
+
+    int max = getFullElements().length;
+    for (int i = 0; i < max; i++) {
+      resetFull();
+      Object o1 = ((List) collection).remove(i);
+      Object o2 = ((List) confirmed).remove(i);
+      assertEquals("remove should return correct element", o1, o2);
+      verify();
+    }
+  }
+
+  /** Returns an empty {@link ArrayList}. */
+  @Override
+  protected Collection makeConfirmedCollection() {
+    ArrayList list = new ArrayList();
+    return list;
+  }
+
+  /** Returns a full {@link ArrayList}. */
+  @Override
+  protected Collection makeConfirmedFullCollection() {
+    ArrayList list = new ArrayList();
+    list.addAll(Arrays.asList(getFullElements()));
+    return list;
+  }
+
+  /** Verifies that the test list implementation matches the confirmed list implementation. */
+  @Override
+  protected void verify() {
+    super.verify();
+
+    List list1 = getList();
+    List list2 = getConfirmedList();
+
+    assertEquals("List should equal confirmed", list1, list2);
+    assertEquals("Confirmed should equal list", list2, list1);
+
+    assertEquals("Hash codes should be equal", list1.hashCode(), list2.hashCode());
+
+    int i = 0;
+    Iterator iterator1 = list1.iterator();
+    Iterator iterator2 = list2.iterator();
+    Object[] array = list1.toArray();
+    while (iterator2.hasNext()) {
+      assertTrue("List iterator should have next", iterator1.hasNext());
+      Object o1 = iterator1.next();
+      Object o2 = iterator2.next();
+      assertEquals("Iterator elements should be equal", o1, o2);
+      o2 = list1.get(i);
+      assertEquals("get should return correct element", o1, o2);
+      o2 = array[i];
+      assertEquals("toArray should have correct element", o1, o2);
+      i++;
+    }
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/TestMap.java b/user/test/com/google/gwt/emultest/java/util/TestMap.java
new file mode 100644
index 0000000..bded458
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TestMap.java
@@ -0,0 +1,1137 @@
+// 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 com.google.gwt.testing.TestUtils;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import jsinterop.annotations.JsPackage;
+import jsinterop.annotations.JsProperty;
+
+/**
+ * Tests base {@link java.util.Map} methods and contracts.
+ * <p>
+ * The forces at work here are similar to those in {@link TestCollection}.
+ * If your class implements the full Map interface, including optional
+ * operations, simply extend this class, and implement the {@link
+ * #makeEmptyMap()} method.
+ * <p>
+ * On the other hand, if your map implemenation is weird, you may have to
+ * override one or more of the other protected methods.  They're described
+ * below.<P>
+ *
+ * <B>Entry Population Methods</B><P>
+ *
+ * Override these methods if your map requires special entries:
+ *
+ * <UL>
+ * <LI>{@link #getSampleKeys()}
+ * <LI>{@link #getSampleValues()}
+ * <LI>{@link #getNewSampleValues()}
+ * <LI>{@link #getOtherKeys()}
+ * <LI>{@link #getOtherValues()}
+ * </UL>
+ *
+ * <B>Supported Operation Methods</B><P>
+ *
+ * Override these methods if your map doesn't support certain operations:
+ *
+ * <UL>
+ * <LI> {@link #useDuplicateValues()}
+ * <LI> {@link #useNullKey()}
+ * <LI> {@link #useNullValue()}
+ * <LI> {@link #isAddRemoveModifiable()}
+ * <LI> {@link #isChangeable()}
+ * </UL>
+ *
+ * <B>Fixture Methods</B><P>
+ *
+ * For tests on modification operations (puts and removes), fixtures are used
+ * to verify that that operation results in correct state for the map and its
+ * collection views.  Basically, the modification is performed against your
+ * map implementation, and an identical modification is performed against
+ * a <I>confirmed</I> map implementation.  A confirmed map implementation is
+ * something like <Code>java.util.HashMap</Code>, which is known to conform
+ * exactly to the {@link Map} contract.  After the modification takes place
+ * on both your map implementation and the confirmed map implementation, the
+ * two maps are compared to see if their state is identical.  The comparison
+ * also compares the collection views to make sure they're still the same.<P>
+ *
+ * The upshot of all that is that <I>any</I> test that modifies the map in
+ * <I>any</I> way will verify that <I>all</I> of the map's state is still
+ * correct, including the state of its collection views.  So for instance
+ * if a key is removed by the map's key set's iterator, then the entry set
+ * is checked to make sure the key/value pair no longer appears.<P>
+ *
+ * The {@link #map} field holds an instance of your collection implementation.
+ * The {@link #entrySet}, {@link #keySet} and {@link #collectionValues} fields hold
+ * that map's collection views.  And 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 maps, so that tests can proceed from a known state.<P>
+ *
+ * After a modification operation to both {@link #map} and {@link #confirmed},
+ * the {@link #verify()} method is invoked to compare the results.  The {@link
+ * verify()} method calls separate methods to verify the map and its three
+ * collection views ({@link verifyMap(), {@link verifyEntrySet()}, {@link
+ * verifyKeySet()}, and {@link verifyValues()}).  You may want to override one
+ * of the verification methodsto perform additional verifications.  For
+ * instance, {@link TestDoubleOrderedMap} would want override its {@link
+ * #verifyValues()} method to verify that the values are unique and in
+ * ascending order.<P>
+ *
+ * <B>Other Notes</B><P>
+ *
+ * If your {@link Map} fails one of these tests by design, you may still use
+ * this base set of cases.  Simply override the test case (method) your {@link
+ * Map} fails and/or the methods that define the assumptions used by the test
+ * cases.  For example, if your map does not allow duplicate values, override
+ * {@link #useDuplicateValues()} and have it return <code>false</code>
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+abstract class TestMap extends TestObject {
+
+  // These instance variables are initialized with the reset method.
+  // Tests for map methods that alter the map (put, putAll, remove)
+  // first call reset() to create the map and its views; then perform
+  // the modification on the map; perform the same modification on the
+  // confirmed; and then call verify() to ensure that the map is equal
+  // to the confirmed, that the already-constructed collection views
+  // are still equal to the confirmed's collection views.
+
+  /** Map created by reset(). */
+  protected Map map;
+
+  /** Entry set of map created by reset(). */
+  protected Set entrySet;
+
+  /** Key set of map created by reset(). */
+  protected Set keySet;
+
+  /** Values collection of map created by reset(). */
+  protected Collection collectionValues;
+
+  /** HashMap created by reset(). */
+  protected Map confirmed;
+
+  /**
+   * Override if your map does not allow a <code>null</code> key. The default implementation returns
+   * <code>true</code>
+   */
+  protected boolean useNullKey() {
+    return true;
+  }
+
+  /**
+   * Override if your map does not allow <code>null</code> values. The default implementation
+   * returns <code>true</code>.
+   */
+  protected boolean useNullValue() {
+    return true;
+  }
+
+  /**
+   * Override if your map does not allow duplicate values. The default implementation returns <code>
+   * true</code>.
+   */
+  protected boolean useDuplicateValues() {
+    return true;
+  }
+
+  /**
+   * Override if your map allows its mappings to be changed to new values. The default
+   * implementation returns <code>true</code>.
+   */
+  protected boolean isChangeable() {
+    return true;
+  }
+
+  /**
+   * Override if your map does not allow add/remove modifications. The default implementation
+   * returns <code>true</code>.
+   */
+  protected boolean isAddRemoveModifiable() {
+    return true;
+  }
+
+  /**
+   * Override if your map allows concurrent modifications. The default implementation returns <code>
+   * true</code>.
+   */
+  protected boolean isFailFastExpected() {
+    return true;
+  }
+
+  /**
+   * Returns the set of keys in the mappings used to test the map. This method must return an array
+   * with the same length as {@link #getSampleValues()} and all array elements must be different.
+   * The default implementation constructs a set of String keys, and includes a single null key if
+   * {@link #useNullKey()} returns <code>true</code>.
+   */
+  protected Object[] getSampleKeys() {
+    Object[] result = {
+      "blah",
+      "foo",
+      "bar",
+      "baz",
+      "tmp",
+      "gosh",
+      "golly",
+      "gee",
+      "hello",
+      "goodbye",
+      "we'll",
+      "see",
+      "you",
+      "all",
+      "again",
+      "key",
+      "key2",
+      useNullKey() ? null : "nonnullkey"
+    };
+    return result;
+  }
+
+  protected Object[] getOtherKeys() {
+    return TestCollection.getOtherNonNullStringElements();
+  }
+
+  protected Object[] getOtherValues() {
+    return TestCollection.getOtherNonNullStringElements();
+  }
+
+  /**
+   * Returns the set of values in the mappings used to test the map. This method must return an
+   * array with the same length as {@link #getSampleKeys()}. The default implementation contructs a
+   * set of String values and includes a single null value if {@link #useNullValue()} returns <code>
+   * true</code>, and includes two values that are the same if {@link #useDuplicateValues()} returns
+   * <code>true</code>.
+   */
+  protected Object[] getSampleValues() {
+    Object[] result = {
+      "blahv",
+      "foov",
+      "barv",
+      "bazv",
+      "tmpv",
+      "goshv",
+      "gollyv",
+      "geev",
+      "hellov",
+      "goodbyev",
+      "we'llv",
+      "seev",
+      "youv",
+      "allv",
+      "againv",
+      useNullValue() ? null : "nonnullvalue",
+      "value",
+      useDuplicateValues() ? "value" : "value2",
+    };
+    return result;
+  }
+
+  /**
+   * Returns a the set of values that can be used to replace the values returned from {@link
+   * #getSampleValues()}. This method must return an array with the same length as {@link
+   * #getSampleValues()}. The values returned from this method should not be the same as those
+   * returned from {@link #getSampleValues()}. The default implementation constructs a set of String
+   * values and includes a single null value if {@link #useNullValue()} returns <code>true</code>,
+   * and includes two values that are the same if {@link #useDuplicateValues()} returns <code>true
+   * </code>.
+   */
+  protected Object[] getNewSampleValues() {
+    Object[] result = {
+      useNullValue() ? null : "newnonnullvalue",
+      "newvalue",
+      useDuplicateValues() ? "newvalue" : "newvalue2",
+      "newblahv",
+      "newfoov",
+      "newbarv",
+      "newbazv",
+      "newtmpv",
+      "newgoshv",
+      "newgollyv",
+      "newgeev",
+      "newhellov",
+      "newgoodbyev",
+      "newwe'llv",
+      "newseev",
+      "newyouv",
+      "newallv",
+      "newagainv",
+    };
+    return result;
+  }
+
+  /**
+   * Helper method to add all the mappings described by {@link #getSampleKeys()} and {@link
+   * #getSampleValues()}.
+   */
+  protected void addSampleMappings(Map m) {
+
+    Object[] keys = getSampleKeys();
+    Object[] values = getSampleValues();
+
+    for (int i = 0; i < keys.length; i++) {
+      try {
+        m.put(keys[i], values[i]);
+      } catch (NullPointerException exception) {
+        assertTrue(
+            "NullPointerException only allowed to be thrown "
+                + "if either the key or value is null.",
+            keys[i] == null || values[i] == null);
+
+        if (keys[i] == null) {
+          if (useNullKey()) {
+            throw new Error(
+                "NullPointerException on null key, but "
+                    + "useNullKey is not overridden to return false.",
+                exception);
+          }
+        } else if (values[i] == null) {
+          if (useNullValue()) {
+            throw new Error(
+                "NullPointerException on null value, but "
+                    + "useNullValue is not overridden to return false.",
+                exception);
+          }
+        } else {
+          // Unknown reason for NullPointer.
+          throw exception;
+        }
+      }
+    }
+    assertEquals("size must reflect number of mappings added.", keys.length, m.size());
+  }
+
+  /** Return a new, empty {@link Map} to be used for testing. */
+  protected abstract Map makeEmptyMap();
+
+  protected Map makeConfirmedMap() {
+    return new HashMap();
+  }
+
+  /**
+   * Return a new, populated map. The mappings in the map should match the keys and values returned
+   * from {@link #getSampleKeys()} and {@link #getSampleValues()}. The default implementation uses
+   * makeEmptyMap() and calls {@link #addSampleMappings()} to add all the mappings to the map.
+   */
+  protected Map makeFullMap() {
+    Map m = makeEmptyMap();
+    addSampleMappings(m);
+    return m;
+  }
+
+  @Override
+  public Object makeObject() {
+    return makeEmptyMap();
+  }
+
+  public void testSpecialKeysValues() {
+    String[] keys = {"toString", "constructor", "__proto__", "", "null"};
+    Object[] values = {new Object(), new Object(), new Object(), new Object(), null};
+
+    Map map = makeEmptyMap();
+
+    assertMap(map, keys, values);
+
+    Object[] undefineds = new Object[values.length];
+    Arrays.fill(undefineds, getUndefined());
+    assertMap(map, keys, undefineds);
+  }
+
+  private void assertMap(Map map, String[] keys, Object[] values) {
+    assertEmptyMap(map, keys, values);
+
+    // Fill the map with special keys/values.
+    for (int i = 0; i < keys.length; i++) {
+      map.put(keys[i], values[i]);
+    }
+
+    // Assert the map with filled in keys/values
+    for (int i = 0; i < keys.length; i++) {
+      assertTrue(keys[i], map.containsKey(keys[i]));
+      assertTrue(keys[i], map.containsValue(values[i]));
+      assertSame(keys[i], values[i], map.get(keys[i]));
+    }
+    assertEquals(map.toString(), keys.length, map.size());
+
+    // Remove the keys and assert the results
+    for (int i = 0; i < keys.length; i++) {
+      assertSame(keys[i], values[i], map.remove(keys[i]));
+    }
+    assertEmptyMap(map, keys, values);
+  }
+
+  private static void assertEmptyMap(Map map, final String[] keys, final Object[] values) {
+    for (int i = 0; i < keys.length; i++) {
+      assertFalse(keys[i], map.containsKey(keys[i]));
+      assertFalse(keys[i], map.containsValue(values[i]));
+      assertNull(keys[i], map.get(keys[i]));
+    }
+  }
+
+  private static Object getUndefined() {
+    if (TestUtils.isJvm()) {
+      return null;
+    }
+    return getUndefinedImpl();
+  }
+
+  @JsProperty(name = "undefined", namespace = JsPackage.GLOBAL)
+  private static native Object getUndefinedImpl();
+
+  /**
+   * Test to ensure the test setup is working properly. This method checks to ensure that the
+   * getSampleKeys and getSampleValues methods are returning results that look appropriate. That is,
+   * they both return a non-null array of equal length. The keys array must not have any duplicate
+   * values, and may only contain a (single) null key if useNullKey() returns true. The values array
+   * must only have a null value if useNullValue() is true and may only have duplicate values if
+   * useDuplicateValues() returns true.
+   */
+  public void testSampleMappings() {
+    Object[] keys = getSampleKeys();
+    Object[] values = getSampleValues();
+    Object[] newValues = getNewSampleValues();
+
+    assertNotNull("failure in test: Must have keys returned from " + "getSampleKeys.", keys);
+
+    assertTrue(
+        "failure in test: Must have values returned from " + "getSampleValues.", values != null);
+
+    // verify keys and values have equivalent lengths (in case getSampleX are
+    // overridden)
+    assertEquals(
+        "failure in test: not the same number of sample " + "keys and values.",
+        keys.length,
+        values.length);
+
+    assertEquals(
+        "failure in test: not the same number of values and new values.",
+        values.length,
+        newValues.length);
+
+    // verify there aren't duplicate keys, and check values
+    for (int i = 0; i < keys.length - 1; i++) {
+      for (int j = i + 1; j < keys.length; j++) {
+        assertTrue("failure in test: duplicate null keys.", (keys[i] != null || keys[j] != null));
+        assertTrue(
+            "failure in test: duplicate non-null key.",
+            (keys[i] == null
+                || keys[j] == null
+                || (!keys[i].equals(keys[j]) && !keys[j].equals(keys[i]))));
+      }
+      assertTrue(
+          "failure in test: found null key, but useNullKey " + "is false.",
+          keys[i] != null || useNullKey());
+      assertTrue(
+          "failure in test: found null value, but useNullValue " + "is false.",
+          values[i] != null || useNullValue());
+      assertTrue(
+          "failure in test: found null new value, but useNullValue " + "is false.",
+          newValues[i] != null || useNullValue());
+      assertTrue(
+          "failure in test: values should not be the same as new value",
+          values[i] != newValues[i] && (values[i] == null || !values[i].equals(newValues[i])));
+    }
+  }
+
+  // tests begin here.  Each test adds a little bit of tested functionality.
+  // Many methods assume previous methods passed.  That is, they do not
+  // exhaustively recheck things that have already been checked in a previous
+  // test methods.
+
+  /**
+   * Test to ensure that makeEmptyMap and makeFull returns a new non-null map with each invocation.
+   */
+  public void testMakeMap() {
+    Map em = makeEmptyMap();
+    assertTrue("failure in test: makeEmptyMap must return a non-null map.", em != null);
+
+    Map em2 = makeEmptyMap();
+    assertTrue("failure in test: makeEmptyMap must return a non-null map.", em != null);
+
+    assertTrue(
+        "failure in test: makeEmptyMap must return a new map " + "with each invocation.",
+        em != em2);
+
+    Map fm = makeFullMap();
+    assertTrue("failure in test: makeFullMap must return a non-null map.", fm != null);
+
+    Map fm2 = makeFullMap();
+    assertTrue("failure in test: makeFullMap must return a non-null map.", fm != null);
+
+    assertTrue(
+        "failure in test: makeFullMap must return a new map " + "with each invocation.", fm != fm2);
+  }
+
+  /** Tests Map.isEmpty() */
+  public void testMapIsEmpty() {
+
+    resetEmpty();
+    assertEquals("Map.isEmpty() should return true with an empty map", true, map.isEmpty());
+    verify();
+
+    resetFull();
+    assertEquals("Map.isEmpty() should return false with a non-empty map", false, map.isEmpty());
+    verify();
+  }
+
+  /** Tests Map.size() */
+  public void testMapSize() {
+    resetEmpty();
+    assertEquals("Map.size() should be 0 with an empty map", 0, map.size());
+    verify();
+
+    resetFull();
+    assertEquals(
+        "Map.size() should equal the number of entries " + "in the map",
+        getSampleKeys().length,
+        map.size());
+    verify();
+  }
+
+  /**
+   * Tests {@link Map#clear()}. If the map {@link #isAddRemoveModifiable() can add and remove
+   * elements}, then {@link Map#size()} and {@link Map#isEmpty()} are used to ensure that map has no
+   * elements after a call to clear. If the map does not support adding and removing elements, this
+   * method checks to ensure clear throws an UnsupportedOperationException.
+   */
+  public void testMapClear() {
+    if (!isAddRemoveModifiable()) {
+      return;
+    }
+
+    resetEmpty();
+    map.clear();
+    confirmed.clear();
+    verify();
+
+    resetFull();
+    map.clear();
+    confirmed.clear();
+    verify();
+  }
+
+  /**
+   * Tests Map.containsKey(Object) by verifying it returns false for all sample keys on a map
+   * created using an empty map and returns true for all sample keys returned on a full map.
+   */
+  public void testMapContainsKey() {
+    Object[] keys = getSampleKeys();
+
+    resetEmpty();
+    for (int i = 0; i < keys.length; i++) {
+      assertTrue("Map must not contain key when map is empty", !map.containsKey(keys[i]));
+    }
+    verify();
+
+    resetFull();
+    for (int i = 0; i < keys.length; i++) {
+      assertTrue(
+          "Map must contain key for a mapping in the map. " + "Missing: " + keys[i],
+          map.containsKey(keys[i]));
+    }
+    verify();
+  }
+
+  /**
+   * Tests Map.containsValue(Object) by verifying it returns false for all sample values on an empty
+   * map and returns true for all sample values on a full map.
+   */
+  public void testMapContainsValue() {
+    Object[] values = getSampleValues();
+
+    resetEmpty();
+    for (int i = 0; i < values.length; i++) {
+      assertTrue("Empty map must not contain value", !map.containsValue(values[i]));
+    }
+    verify();
+
+    resetFull();
+    for (int i = 0; i < values.length; i++) {
+      assertTrue("Map must contain value for a mapping in the map.", map.containsValue(values[i]));
+    }
+    verify();
+  }
+
+  /** Tests Map.equals(Object) */
+  public void testMapEquals() {
+    resetEmpty();
+    assertTrue("Empty maps unequal.", map.equals(confirmed));
+    verify();
+
+    resetFull();
+    assertTrue("Full maps unequal.", map.equals(confirmed));
+    verify();
+
+    resetFull();
+    // modify the HashMap created from the full map and make sure this
+    // change results in map.equals() to return false.
+    Iterator iter = confirmed.keySet().iterator();
+    iter.next();
+    iter.remove();
+    assertTrue("Different maps equal.", !map.equals(confirmed));
+
+    resetFull();
+    assertTrue("equals(null) returned true.", !map.equals(null));
+    assertTrue("equals(new Object()) returned true.", !map.equals(new Object()));
+    verify();
+  }
+
+  /** Tests Map.get(Object) */
+  public void testMapGet() {
+    resetEmpty();
+
+    Object[] keys = getSampleKeys();
+    Object[] values = getSampleValues();
+
+    for (int i = 0; i < keys.length; i++) {
+      assertTrue("Empty map.get() should return null.", map.get(keys[i]) == null);
+    }
+    verify();
+
+    resetFull();
+    for (int i = 0; i < keys.length; i++) {
+      assertEquals("Full map.get() should return value from mapping.", values[i], map.get(keys[i]));
+    }
+  }
+
+  /** Tests Map.hashCode() */
+  public void testMapHashCode() {
+    resetEmpty();
+    assertTrue("Empty maps have different hashCodes.", map.hashCode() == confirmed.hashCode());
+
+    resetFull();
+    assertTrue("Equal maps have different hashCodes.", map.hashCode() == confirmed.hashCode());
+  }
+
+  /**
+   * Tests Map.toString(). Since the format of the string returned by the toString() method is not
+   * defined in the Map interface, there is no common way to test the results of the toString()
+   * method. Thereforce, it is encouraged that Map implementations override this test with one that
+   * checks the format matches any format defined in its API. This default implementation just
+   * verifies that the toString() method does not return null.
+   */
+  public void testMapToString() {
+    resetEmpty();
+    assertTrue("Empty map toString() should not return null", map.toString() != null);
+    verify();
+
+    resetFull();
+    assertTrue("Empty map toString() should not return null", map.toString() != null);
+    verify();
+  }
+
+  /** Tests Map.put(Object, Object) */
+  public void testMapPut() {
+    if (!isAddRemoveModifiable()) {
+      return;
+    }
+
+    resetEmpty();
+
+    Object[] keys = getSampleKeys();
+    Object[] values = getSampleValues();
+    Object[] newValues = getNewSampleValues();
+
+    for (int i = 0; i < keys.length; i++) {
+      Object o = map.put(keys[i], values[i]);
+      confirmed.put(keys[i], values[i]);
+      verify();
+      assertTrue("First map.put should return null", o == null);
+      assertTrue("Map should contain key after put", map.containsKey(keys[i]));
+      assertTrue("Map should contain value after put", map.containsValue(values[i]));
+    }
+
+    for (int i = 0; i < keys.length; i++) {
+      Object o = map.put(keys[i], newValues[i]);
+      confirmed.put(keys[i], newValues[i]);
+      verify();
+      assertEquals("Second map.put should return previous value", values[i], o);
+      assertTrue("Map should still contain key after put", map.containsKey(keys[i]));
+      assertTrue("Map should contain new value after put", map.containsValue(newValues[i]));
+
+      // if duplicates are allowed, we're not guarunteed that the value
+      // no longer exists, so don't try checking that.
+      if (!useDuplicateValues()) {
+        assertTrue(
+            "Map should not contain old value after second put", !map.containsValue(values[i]));
+      }
+    }
+  }
+
+  /** Tests Map.putAll(Collection) */
+  public void testMapPutAll() {
+    if (!isAddRemoveModifiable()) {
+      return;
+    }
+
+    resetEmpty();
+
+    Map m2 = makeFullMap();
+
+    map.putAll(m2);
+    confirmed.putAll(m2);
+    verify();
+
+    resetEmpty();
+
+    m2 = new HashMap();
+    Object[] keys = getSampleKeys();
+    Object[] values = getSampleValues();
+    for (int i = 0; i < keys.length; i++) {
+      m2.put(keys[i], values[i]);
+    }
+
+    map.putAll(m2);
+    confirmed.putAll(m2);
+    verify();
+  }
+
+  /** Tests Map.remove(Object) */
+  public void testMapRemove() {
+    if (!isAddRemoveModifiable()) {
+      return;
+    }
+
+    resetEmpty();
+
+    Object[] keys = getSampleKeys();
+    Object[] values = getSampleValues();
+    for (int i = 0; i < keys.length; i++) {
+      Object o = map.remove(keys[i]);
+      assertTrue("First map.remove should return null", o == null);
+    }
+    verify();
+
+    resetFull();
+
+    for (int i = 0; i < keys.length; i++) {
+      Object o = map.remove(keys[i]);
+      confirmed.remove(keys[i]);
+      verify();
+
+      assertEquals("map.remove with valid key should return value", values[i], o);
+    }
+
+    Object[] other = getOtherKeys();
+
+    resetFull();
+    int size = map.size();
+    for (int i = 0; i < other.length; i++) {
+      Object o = map.remove(other[i]);
+      assertEquals("map.remove for nonexistent key should return null", o, null);
+      assertEquals("map.remove for nonexistent key should not " + "shrink map", size, map.size());
+    }
+    verify();
+  }
+
+  public void testFailFastEntrySet() {
+    if (!isAddRemoveModifiable()) {
+      return;
+    }
+    if (!isFailFastExpected()) {
+      return;
+    }
+    resetFull();
+    Iterator<Map.Entry> it = map.entrySet().iterator();
+    final Map.Entry val = it.next();
+    map.remove(val.getKey());
+    try {
+      it.next();
+      fail();
+    } catch (ConcurrentModificationException expected) {
+    }
+
+    resetFull();
+    it = map.entrySet().iterator();
+    it.next();
+    map.clear();
+    try {
+      it.next();
+      fail();
+    } catch (ConcurrentModificationException expected) {
+    }
+  }
+
+  public void testFailFastKeySet() {
+    if (!isAddRemoveModifiable()) {
+      return;
+    }
+    if (!isFailFastExpected()) {
+      return;
+    }
+    resetFull();
+    Iterator it = map.keySet().iterator();
+    final Object val = it.next();
+    map.remove(val);
+    try {
+      it.next();
+      fail();
+    } catch (ConcurrentModificationException expected) {
+    }
+
+    resetFull();
+    it = map.keySet().iterator();
+    it.next();
+    map.clear();
+    try {
+      it.next();
+      fail();
+    } catch (ConcurrentModificationException expected) {
+    }
+  }
+
+  public void testFailFastValues() {
+    if (!isAddRemoveModifiable()) {
+      return;
+    }
+    if (!isFailFastExpected()) {
+      return;
+    }
+    resetFull();
+    Iterator it = map.values().iterator();
+    it.next();
+    map.remove(map.keySet().iterator().next());
+    try {
+      it.next();
+      fail();
+    } catch (ConcurrentModificationException expected) {
+    }
+
+    resetFull();
+    it = map.values().iterator();
+    it.next();
+    map.clear();
+    try {
+      it.next();
+      fail();
+    } catch (ConcurrentModificationException expected) {
+    }
+  }
+
+  /**
+   * Utility methods to create an array of Map.Entry objects out of the given key and value arrays.
+   *
+   * <p>
+   *
+   * @param keys the array of keys
+   * @param values the array of values
+   * @return an array of Map.Entry of those keys to those values
+   */
+  private Map.Entry[] makeEntryArray(Object[] keys, Object[] values) {
+    Map.Entry[] result = new Map.Entry[keys.length];
+    for (int i = 0; i < keys.length; i++) {
+      result[i] = new DefaultMapEntry(keys[i], values[i]);
+    }
+    return result;
+  }
+
+  class TestMapEntrySet extends TestSet {
+    public TestMapEntrySet() {
+      super("");
+    }
+
+    // Have to implement manually; entrySet doesn't support addAll
+    @Override
+    protected Object[] getFullElements() {
+      Object[] k = getSampleKeys();
+      Object[] v = getSampleValues();
+      return makeEntryArray(k, v);
+    }
+
+    // Have to implement manually; entrySet doesn't support addAll
+    @Override
+    protected Object[] getOtherElements() {
+      Object[] k = getOtherKeys();
+      Object[] v = getOtherValues();
+      return makeEntryArray(k, v);
+    }
+
+    @Override
+    protected Set makeEmptySet() {
+      return makeEmptyMap().entrySet();
+    }
+
+    @Override
+    protected Set makeFullSet() {
+      return makeFullMap().entrySet();
+    }
+
+    @Override
+    protected boolean isAddSupported() {
+      // Collection views don't support add operations.
+      return false;
+    }
+
+    @Override
+    protected boolean isRemoveSupported() {
+      // Entry set should only support remove if map does
+      return isAddRemoveModifiable();
+    }
+
+    @Override
+    protected void resetFull() {
+      TestMap.this.resetFull();
+      collection = map.entrySet();
+      TestMapEntrySet.this.confirmed = TestMap.this.confirmed.entrySet();
+    }
+
+    @Override
+    protected void resetEmpty() {
+      TestMap.this.resetEmpty();
+      collection = map.entrySet();
+      TestMapEntrySet.this.confirmed = TestMap.this.confirmed.entrySet();
+    }
+
+    @Override
+    protected void verify() {
+      super.verify();
+      TestMap.this.verify();
+    }
+  }
+
+  class TestMapKeySet extends TestSet {
+    public TestMapKeySet() {
+      super("");
+    }
+
+    @Override
+    protected Object[] getFullElements() {
+      return getSampleKeys();
+    }
+
+    @Override
+    protected Object[] getOtherElements() {
+      return getOtherKeys();
+    }
+
+    @Override
+    protected Set makeEmptySet() {
+      return makeEmptyMap().keySet();
+    }
+
+    @Override
+    protected Set makeFullSet() {
+      return makeFullMap().keySet();
+    }
+
+    @Override
+    protected boolean isAddSupported() {
+      return false;
+    }
+
+    @Override
+    protected boolean isRemoveSupported() {
+      return isAddRemoveModifiable();
+    }
+
+    @Override
+    protected void resetEmpty() {
+      TestMap.this.resetEmpty();
+      collection = map.keySet();
+      TestMapKeySet.this.confirmed = TestMap.this.confirmed.keySet();
+    }
+
+    @Override
+    protected void resetFull() {
+      TestMap.this.resetFull();
+      collection = map.keySet();
+      TestMapKeySet.this.confirmed = TestMap.this.confirmed.keySet();
+    }
+
+    @Override
+    protected void verify() {
+      super.verify();
+      TestMap.this.verify();
+    }
+  }
+
+  class TestMapValues extends TestCollection {
+    public TestMapValues() {}
+
+    @Override
+    protected Object[] getFullElements() {
+      return getSampleValues();
+    }
+
+    @Override
+    protected Object[] getOtherElements() {
+      return getOtherValues();
+    }
+
+    @Override
+    protected Collection makeCollection() {
+      return makeEmptyMap().values();
+    }
+
+    @Override
+    protected Collection makeFullCollection() {
+      return makeFullMap().values();
+    }
+
+    @Override
+    protected boolean isAddSupported() {
+      return false;
+    }
+
+    @Override
+    protected boolean isRemoveSupported() {
+      return isAddRemoveModifiable();
+    }
+
+    @Override
+    protected boolean areEqualElementsDistinguishable() {
+      // equal values are associated with different keys, so they are
+      // distinguishable.
+      return true;
+    }
+
+    @Override
+    protected Collection makeConfirmedCollection() {
+      // never gets called, reset methods are overridden
+      return null;
+    }
+
+    @Override
+    protected Collection makeConfirmedFullCollection() {
+      // never gets called, reset methods are overridden
+      return null;
+    }
+
+    @Override
+    protected void resetFull() {
+      TestMap.this.resetFull();
+      collection = map.values();
+      TestMapValues.this.confirmed = TestMap.this.confirmed.values();
+    }
+
+    @Override
+    protected void resetEmpty() {
+      TestMap.this.resetEmpty();
+      collection = map.values();
+      TestMapValues.this.confirmed = TestMap.this.confirmed.values();
+    }
+
+    @Override
+    protected void verify() {
+      super.verify();
+      TestMap.this.verify();
+    }
+
+    // TODO: should test that a remove on the values collection view
+    // removes the proper mapping and not just any mapping that may have
+    // the value equal to the value returned from the values iterator.
+  }
+
+  /**
+   * Resets the {@link #map}, {@link #entrySet}, {@link #keySet}, {@link #collectionValues} and
+   * {@link #confirmed} fields to empty.
+   */
+  protected void resetEmpty() {
+    this.map = makeEmptyMap();
+    views();
+    this.confirmed = makeConfirmedMap();
+  }
+
+  /**
+   * Resets the {@link #map}, {@link #entrySet}, {@link #keySet}, {@link #collectionValues} and
+   * {@link #confirmed} fields to full.
+   */
+  protected void resetFull() {
+    this.map = makeFullMap();
+    views();
+    this.confirmed = makeConfirmedMap();
+    Object[] k = getSampleKeys();
+    Object[] v = getSampleValues();
+    for (int i = 0; i < k.length; i++) {
+      confirmed.put(k[i], v[i]);
+    }
+  }
+
+  /** Resets the collection view fields. */
+  private void views() {
+    this.keySet = map.keySet();
+    this.collectionValues = map.values();
+    this.entrySet = map.entrySet();
+  }
+
+  /**
+   * Verifies that {@link #map} is still equal to {@link #confirmed}. This method checks that the
+   * map is equal to the HashMap, <I>and</I> that the map's collection views are still equal to the
+   * HashMap's collection views. An <Code>equals</Code> test is done on the maps and their
+   * collection views; their size and <Code>isEmpty</Code> results are compared; their hashCodes are
+   * compared; and <Code>containsAll</Code> tests are run on the collection views.
+   */
+  protected void verify() {
+    verifyMap();
+    verifyEntrySet();
+    verifyKeySet();
+  }
+
+  protected void verifyMap() {
+    int size = confirmed.size();
+    boolean empty = confirmed.isEmpty();
+    assertEquals("Map should be same size as HashMap", size, map.size());
+    assertEquals("Map should be empty if HashMap is", empty, map.isEmpty());
+    assertEquals("hashCodes should be the same", confirmed.hashCode(), map.hashCode());
+    // this fails for LRUMap because confirmed.equals() somehow modifies
+    // map, causing concurrent modification exceptions.
+    // assertEquals("Map should still equal HashMap", confirmed, map);
+    // this works though and performs the same verification:
+    assertTrue("Map should still equal HashMap", map.equals(confirmed));
+    // TODO: this should really be rexamined to figure out why LRU map
+    // behaves like it does (the equals shouldn't modify since all accesses
+    // by the confirmed collection should be through an iterator, thus not
+    // causing LRUMap to change).
+  }
+
+  protected void verifyEntrySet() {
+    int size = confirmed.size();
+    boolean empty = confirmed.isEmpty();
+    assertEquals("entrySet should be same size as HashMap's", size, entrySet.size());
+    assertEquals("entrySet should be empty if HashMap is", empty, entrySet.isEmpty());
+    assertTrue(
+        "entrySet should contain all HashMap's elements",
+        entrySet.containsAll(confirmed.entrySet()));
+    assertEquals(
+        "entrySet hashCodes should be the same",
+        confirmed.entrySet().hashCode(),
+        entrySet.hashCode());
+    assertEquals("Map's entry set should still equal HashMap's", confirmed.entrySet(), entrySet);
+  }
+
+  protected void verifyKeySet() {
+    int size = confirmed.size();
+    boolean empty = confirmed.isEmpty();
+    assertEquals("keySet should be same size as HashMap's", size, keySet.size());
+    assertEquals("keySet should be empty if HashMap is", empty, keySet.isEmpty());
+    assertTrue(
+        "keySet should contain all HashMap's elements", keySet.containsAll(confirmed.keySet()));
+    assertEquals(
+        "keySet hashCodes should be the same", confirmed.keySet().hashCode(), keySet.hashCode());
+    assertEquals("Map's key set should still equal HashMap's", confirmed.keySet(), keySet);
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/TestObject.java b/user/test/com/google/gwt/emultest/java/util/TestObject.java
new file mode 100644
index 0000000..20d9c42
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TestObject.java
@@ -0,0 +1,124 @@
+// 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;
+
+/**
+ * Tests base {@link java.lang.Object} methods and contracts.
+ *
+ * <p>To use, simply extend this class, and implement the {@link #makeObject()} method.
+ *
+ * <p>If your {@link Object} fails one of these tests by design, you may still use this base set of
+ * cases. Simply override the test case (method) your {@link Object} fails.
+ */
+abstract class TestObject extends EmulTestBase {
+
+  // current major release for Collections
+  public static final int COLLECTIONS_MAJOR_VERSION = 2;
+
+  /**
+   * This constant makes it possible for TestMap (and other subclasses, if necessary) to
+   * automatically check CVS for a versionX copy of a Serialized object, so we can make sure that
+   * compatibility is maintained. See, for example, TestMap.getCanonicalFullMapName(Map map).
+   * Subclasses can override this variable, indicating compatibility with earlier Collections
+   * versions. Defaults to 1, the earliest Collections version. (Note: some collections did not even
+   * exist in this version).
+   *
+   * @return 1
+   */
+  public int getCompatibilityVersion() {
+    return 1;
+  }
+
+  /** Return a new, empty {@link Object} to used for testing. */
+  public abstract Object makeObject();
+
+  public void testObjectEqualsSelf() {
+    Object obj = makeObject();
+    assertEquals("A Object should equal itself", obj, obj);
+  }
+
+  public void testObjectHashCodeEqualsSelfHashCode() {
+    Object obj = makeObject();
+    assertEquals("hashCode should be repeatable", obj.hashCode(), obj.hashCode());
+  }
+
+  public void testObjectHashCodeEqualsContract() {
+    Object obj1 = makeObject();
+    if (obj1.equals(obj1)) {
+      assertEquals(
+          "[1] When two objects are equal, their hashCodes should be also.",
+          obj1.hashCode(),
+          obj1.hashCode());
+    }
+    Object obj2 = makeObject();
+    if (obj1.equals(obj2)) {
+      assertEquals(
+          "[2] When two objects are equal, their hashCodes should be also.",
+          obj1.hashCode(),
+          obj2.hashCode());
+      assertTrue(
+          "When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true",
+          obj2.equals(obj1));
+    }
+  }
+
+  public String getCanonicalEmptyCollectionName(Object object) {
+    StringBuilder retval = new StringBuilder();
+    retval.append("data/test/");
+    String colName = object.getClass().getName();
+
+    colName = colName.substring(colName.lastIndexOf(".") + 1);
+    retval.append(colName);
+    retval.append(".emptyCollection.version");
+    retval.append(getCompatibilityVersion());
+    retval.append(".obj");
+    return retval.toString();
+  }
+
+  public String getCanonicalFullCollectionName(Object object) {
+    StringBuilder retval = new StringBuilder();
+    retval.append("data/test/");
+    String colName = object.getClass().getName();
+    colName = colName.substring(colName.lastIndexOf(".") + 1);
+    retval.append(colName);
+    retval.append(".fullCollection.version");
+    retval.append(getCompatibilityVersion());
+    retval.append(".obj");
+    return retval.toString();
+  }
+
+  /**
+   * Override this method if a subclass is testing a Collections that cannot serialize an "empty"
+   * Collection (e.g. Comparators have no contents)
+   *
+   * @return true
+   */
+  public boolean supportsEmptyCollections() {
+    return true;
+  }
+
+  /**
+   * Override this method if a subclass is testing a Collections that cannot serialize a "full"
+   * Collection (e.g. Comparators have no contents)
+   *
+   * @return true
+   */
+  public boolean supportsFullCollections() {
+    return true;
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/TestSet.java b/user/test/com/google/gwt/emultest/java/util/TestSet.java
new file mode 100644
index 0000000..aafb85e
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/TestSet.java
@@ -0,0 +1,163 @@
+// 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.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Tests base {@link Set} methods and contracts.
+ *
+ * <p>Since {@link Set} doesn't stipulate much new behavior that isn't already found in {@link
+ * Collection}, this class basically just adds tests for {@link Set#equals()} and {@link
+ * Set#hashCode()} along with an updated {@link #verify()} that ensures elements do not appear more
+ * than once in the set.
+ *
+ * <p>To use, subclass and override the {@link #makeEmptySet()} method. You may have to override
+ * other protected methods if your set is not modifiable, or if your set restricts what kinds of
+ * elements may be added; see {@link TestCollection} for more details.
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+abstract class TestSet extends TestCollection {
+
+  /**
+   * Constructor.
+   *
+   * @param name name for test
+   */
+  public TestSet(String name) {}
+
+  /**
+   * Makes an empty collection by invoking {@link #makeEmptySet()}.
+   *
+   * @return an empty collection
+   */
+  @Override
+  protected final Collection makeCollection() {
+    return makeEmptySet();
+  }
+
+  /**
+   * Makes a full collection by invoking {@link #makeFullSet()}.
+   *
+   * @return a full collection
+   */
+  @Override
+  protected final Collection makeFullCollection() {
+    return makeFullSet();
+  }
+
+  /** Return the {@link TestCollection#collection} fixture, but cast as a Set. */
+  protected Set getSet() {
+    return (Set) collection;
+  }
+
+  /**
+   * Returns an empty {@link HashSet} for use in modification testing.
+   *
+   * @return a confirmed empty collection
+   */
+  @Override
+  protected Collection makeConfirmedCollection() {
+    return new HashSet();
+  }
+
+  /**
+   * Returns a full {@link HashSet} for use in modification testing.
+   *
+   * @return a confirmed full collection
+   */
+  @Override
+  protected Collection makeConfirmedFullCollection() {
+    HashSet set = new HashSet();
+    set.addAll(Arrays.asList(getFullElements()));
+    return set;
+  }
+
+  /** Return the {@link TestCollection#confirmed} fixture, but cast as a Set. */
+  protected Set getConfirmedSet() {
+    return (Set) confirmed;
+  }
+
+  /**
+   * Makes an empty set. The returned set should have no elements.
+   *
+   * @return an empty set
+   */
+  protected abstract Set makeEmptySet();
+
+  /**
+   * Makes a full set by first creating an empty set and then adding all the elements returned by
+   * {@link #getFullElements()}.
+   *
+   * <p>Override if your set does not support the add operation.
+   *
+   * @return a full set
+   */
+  protected Set makeFullSet() {
+    Set set = makeEmptySet();
+    set.addAll(Arrays.asList(getFullElements()));
+    return set;
+  }
+
+  /** Tests {@link Set#equals(Object)}. */
+  public void testSetEquals() {
+    resetEmpty();
+    assertEquals("Empty sets should be equal", getSet(), getConfirmedSet());
+    verify();
+
+    HashSet set2 = new HashSet();
+    set2.add("foo");
+    assertFalse("Empty set shouldn't equal nonempty set", getSet().equals(set2));
+
+    resetFull();
+    assertEquals("Full sets should be equal", getSet(), getConfirmedSet());
+    verify();
+
+    set2.clear();
+    set2.addAll(Arrays.asList(getOtherElements()));
+    assertTrue("Sets with different contents shouldn't be equal", !getSet().equals(set2));
+  }
+
+  /** Tests {@link Set#hashCode()}. */
+  public void testSetHashCode() {
+    resetEmpty();
+    assertEquals(
+        "Empty sets have equal hashCodes", getSet().hashCode(), getConfirmedSet().hashCode());
+
+    resetFull();
+    assertEquals(
+        "Equal sets have equal hashCodes", getSet().hashCode(), getConfirmedSet().hashCode());
+  }
+
+  /** Provides additional verifications for sets. */
+  @Override
+  protected void verify() {
+    super.verify();
+    assertEquals("Sets should be equal", confirmed, collection);
+    assertEquals("Sets should have equal hashCodes", confirmed.hashCode(), collection.hashCode());
+    HashSet set = new HashSet();
+    Iterator iterator = collection.iterator();
+    while (iterator.hasNext()) {
+      assertTrue("Set.iterator should only return unique elements", set.add(iterator.next()));
+    }
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java b/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
index 84b2d24..df8b397 100644
--- a/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
@@ -16,9 +16,6 @@
 package com.google.gwt.emultest.java.util;
 
 import com.google.gwt.testing.TestUtils;
-
-import org.apache.commons.collections.TestMap;
-
 import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -41,12 +38,8 @@
  *
  * @param <K> The key type for the underlying TreeMap
  * @param <V> The value type for the underlying TreeMap
- *
- * TODO(jat): this whole structure needs work. Ideally we would port a new
- * Apache collections test to GWT, but that is not an insignificant amount of
- * work.
  */
-public abstract class TreeMapTest<K extends Comparable<K>, V> extends TestMap {
+abstract class TreeMapTest<K extends Comparable<K>, V> extends TestMap {
 
   private static class ConflictingKey implements Comparable<CharSequence> {
     private final String value;
@@ -91,15 +84,13 @@
   }
 
   /**
-   * Verify that two Collections are deeply equivalent. Some of the Sets that
-   * need to be verified do not implement a sensible equals method
-   * (TreeMap.values for example).
+   * Verify that two Collections are deeply equivalent. Some of the Sets that need to be verified do
+   * not implement a sensible equals method (TreeMap.values for example).
    *
    * @param expected
    * @param actual
    */
-  private static <T> void _assertEquals(Collection<T> expected,
-      Collection<T> actual) {
+  private static <T> void _assertEquals(Collection<T> expected, Collection<T> actual) {
     // verify equivalence using collection interface
     assertEquals(expected.isEmpty(), actual.isEmpty());
     assertEquals(expected.size(), actual.size());
@@ -137,9 +128,8 @@
    * @param expected
    * @param actual
    */
-  private static <K, V> void _assertEquals(SortedMap<K, V> expected,
-      SortedMap<K, V> actual) {
-    _assertEquals((Map<K, V>) expected, (Map<K, V>) actual);
+  private static <K, V> void _assertEquals(SortedMap<K, V> expected, SortedMap<K, V> actual) {
+    _assertEquals(expected, (Map<K, V>) actual);
 
     // verify the order of the associated collections
     assertEquals(expected.keySet().toArray(), actual.keySet().toArray());
@@ -148,8 +138,7 @@
   }
 
   /**
-   * Create the expected return of toString for a Map containing only the passed
-   * key and value.
+   * Create the expected return of toString for a Map containing only the passed key and value.
    *
    * @param key
    * @param value
@@ -166,8 +155,8 @@
   }
 
   /**
-   * Verify entry to be immutable and to have correct values of {@code Map.Entry#toString()}
-   * and {@code Map.Entry#hashCode()}.
+   * Verify entry to be immutable and to have correct values of {@code Map.Entry#toString()} and
+   * {@code Map.Entry#hashCode()}.
    */
   @SuppressWarnings("unchecked")
   private static void verifyEntry(Entry entry) {
@@ -178,22 +167,21 @@
     }
     Object key = entry.getKey();
     Object value = entry.getValue();
-    int expectedHashCode = (key == null ? 0 : key.hashCode())
-        ^ (value == null ? 0 : value.hashCode());
+    int expectedHashCode =
+        (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
     assertEquals(expectedHashCode, entry.hashCode());
     assertEquals(key + "=" + value, entry.toString());
   }
 
-  /**
-   * comparator used when creating the SortedMap.
-   */
+  /** comparator used when creating the SortedMap. */
   private Comparator<K> comparator = null;
-  private boolean isClearSupported = true;
-  private boolean isNullKeySupported = true;
-  private boolean isNullValueSupported = true;
-  private boolean isPutAllSupported = true;
-  private boolean isPutSupported = true;
-  private boolean isRemoveSupported = true;
+
+  private final boolean isClearSupported = true;
+  private final boolean isNullKeySupported = true;
+  private final boolean isNullValueSupported = true;
+  private final boolean isPutAllSupported = true;
+  private final boolean isPutSupported = true;
+  private final boolean isRemoveSupported = true;
 
   @Override
   public String getModuleName() {
@@ -289,9 +277,7 @@
     }
   }
 
-  /**
-   * Test method for 'java.lang.Object.clone()'.
-   */
+  /** Test method for 'java.lang.Object.clone()'. */
   public void testClone() {
     // Map<K, V> map = createMap();
     // Check empty clone behavior
@@ -333,12 +319,13 @@
     assertNull(treeMap.comparator());
     assertNull(secondTreeMap.comparator());
 
-    final Comparator<? super K> customComparator = new Comparator<K>() {
-      @Override
-      public int compare(K o1, K o2) {
-        return o1.compareTo(o2);
-      }
-    };
+    final Comparator<? super K> customComparator =
+        new Comparator<K>() {
+          @Override
+          public int compare(K o1, K o2) {
+            return o1.compareTo(o2);
+          }
+        };
     treeMap = new TreeMap<>(customComparator);
     secondTreeMap = new TreeMap<>(treeMap);
     assertSame(customComparator, treeMap.comparator());
@@ -680,7 +667,7 @@
       keys.remove(null);
     }
 
-    Comparator<? super K> cmp = ((TreeMap<K, V>) map).comparator();
+    Comparator<? super K> cmp = map.comparator();
     Collections.sort(keys, Collections.reverseOrder(cmp));
     Iterator<K> it = map.descendingKeySet().iterator();
     for (K key : keys) {
@@ -748,22 +735,24 @@
   public void testEntrySet_add_throwsUnsupportedOperationException() {
     Map<K, V> map = createMap();
     try {
-      map.entrySet().add(new Entry<K, V>() {
-        @Override
-        public K getKey() {
-          return null;
-        }
+      map.entrySet()
+          .add(
+              new Entry<K, V>() {
+                @Override
+                public K getKey() {
+                  return null;
+                }
 
-        @Override
-        public V getValue() {
-          return null;
-        }
+                @Override
+                public V getValue() {
+                  return null;
+                }
 
-        @Override
-        public V setValue(V value) {
-          return null;
-        }
-      });
+                @Override
+                public V setValue(V value) {
+                  return null;
+                }
+              });
       fail("expected exception");
     } catch (UnsupportedOperationException e) {
       // expected outcome
@@ -1652,7 +1641,6 @@
    * Test method for 'java.util.Map.isEmpty()'.
    *
    * @see java.util.Map#isEmpty()
-   *
    */
   public void testIsEmpty() {
     K[] keys = getKeys();
@@ -2034,7 +2022,7 @@
     for (Object key : getSampleKeys()) {
       keys.add((K) key);
     }
-    Comparator<? super K> cmp = ((TreeMap<K, V>) map).comparator();
+    Comparator<? super K> cmp = map.comparator();
     Collections.sort(keys, cmp);
     Iterator<K> it = map.navigableKeySet().iterator();
     for (K key : keys) {
@@ -2156,15 +2144,14 @@
   }
 
   /**
-   * Test method for 'java.util.Map.put(Object, Object)'. This test shows some
-   * bad behavior of the TreeMap class before JDK 7. A mapping with null key can
-   * be put in but several methods are are unusable afterward.
+   * Test method for 'java.util.Map.put(Object, Object)'. This test shows some bad behavior of the
+   * TreeMap class before JDK 7. A mapping with null key can be put in but several methods are are
+   * unusable afterward.
    *
-   * A SortedMap with natural ordering (no comparator) is supposed to throw a
-   * null pointer exception if a null keys are "not supported". For a natural
-   * ordered TreeMap before JDK 7, a null pointer exception is not thrown. But,
-   * the map is left in a state where any other key based methods result in a
-   * null pointer exception.
+   * <p>A SortedMap with natural ordering (no comparator) is supposed to throw a null pointer
+   * exception if a null keys are "not supported". For a natural ordered TreeMap before JDK 7, a
+   * null pointer exception is not thrown. But, the map is left in a state where any other key based
+   * methods result in a null pointer exception.
    *
    * @see java.util.Map#put(Object, Object)
    */
@@ -2306,8 +2293,7 @@
   }
 
   public void testPut_ComparableKey() {
-    final boolean java6CompatibleSources =
-        !TestUtils.isJvm() || TestUtils.getJdkVersion() < 7;
+    final boolean java6CompatibleSources = !TestUtils.isJvm() || TestUtils.getJdkVersion() < 7;
     TreeMap map = new TreeMap();
     ConflictingKey conflictingKey = new ConflictingKey("conflictingKey");
     try {
@@ -2814,8 +2800,8 @@
       fail("Should throw an IllegalArgumentException");
     } catch (IllegalArgumentException expected) {
     }
-    assertEquals(keys.length,
-        map.subMap(getLessThanMinimumKey(), getGreaterThanMaximumKey()).size());
+    assertEquals(
+        keys.length, map.subMap(getLessThanMinimumKey(), getGreaterThanMaximumKey()).size());
   }
 
   /**
@@ -2842,14 +2828,14 @@
     assertEquals(0, map.subMap(keys[0], keys[0]).size());
     // bounded by a "wide" range
     assertEquals(1, map.subMap(getLessThanMinimumKey(), getGreaterThanMaximumKey()).size());
-    assertEquals(1, map.subMap(getLessThanMinimumKey(), false,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, map.subMap(getLessThanMinimumKey(), true,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, map.subMap(getLessThanMinimumKey(), false,
-        getGreaterThanMaximumKey(), true).size());
-    assertEquals(1, map.subMap(getLessThanMinimumKey(), true,
-        getGreaterThanMaximumKey(), true).size());
+    assertEquals(
+        1, map.subMap(getLessThanMinimumKey(), false, getGreaterThanMaximumKey(), false).size());
+    assertEquals(
+        1, map.subMap(getLessThanMinimumKey(), true, getGreaterThanMaximumKey(), false).size());
+    assertEquals(
+        1, map.subMap(getLessThanMinimumKey(), false, getGreaterThanMaximumKey(), true).size());
+    assertEquals(
+        1, map.subMap(getLessThanMinimumKey(), true, getGreaterThanMaximumKey(), true).size());
 
     // test with two entry map
     map.put(keys[1], values[1]);
@@ -2860,36 +2846,26 @@
     assertEquals(0, map.subMap(keys[0], false, keys[1], false).size());
 
     assertEquals(1, map.subMap(keys[0], false, keys[1], true).size());
-    assertEquals(keys[1], map.subMap(keys[0], false,
-        keys[1], true).keySet().toArray()[0]);
+    assertEquals(keys[1], map.subMap(keys[0], false, keys[1], true).keySet().toArray()[0]);
 
     assertEquals(1, map.subMap(keys[0], true, keys[1], false).size());
-    assertEquals(keys[0], map.subMap(keys[0], true,
-        keys[1], false).keySet().toArray()[0]);
+    assertEquals(keys[0], map.subMap(keys[0], true, keys[1], false).keySet().toArray()[0]);
 
     assertEquals(2, map.subMap(keys[0], true, keys[1], true).size());
-    assertEquals(keys[0], map.subMap(keys[0], true,
-        keys[1], true).keySet().toArray()[0]);
-    assertEquals(keys[1], map.subMap(keys[0], true,
-        keys[1], true).keySet().toArray()[1]);
+    assertEquals(keys[0], map.subMap(keys[0], true, keys[1], true).keySet().toArray()[0]);
+    assertEquals(keys[1], map.subMap(keys[0], true, keys[1], true).keySet().toArray()[1]);
 
     // bounded by a "wide" range
     assertEquals(2, map.subMap(getLessThanMinimumKey(), getGreaterThanMaximumKey()).size());
 
-    assertEquals(2, map.subMap(getLessThanMinimumKey(), false,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, map.subMap(keys[0], false,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(0, map.subMap(keys[0], false,
-        keys[1], false).size());
-    assertEquals(2, map.subMap(keys[0], true,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, map.subMap(keys[0], true,
-        keys[1], false).size());
-    assertEquals(2, map.subMap(keys[0], true,
-        getGreaterThanMaximumKey(), true).size());
-    assertEquals(2, map.subMap(keys[0], true,
-        keys[1], true).size());
+    assertEquals(
+        2, map.subMap(getLessThanMinimumKey(), false, getGreaterThanMaximumKey(), false).size());
+    assertEquals(1, map.subMap(keys[0], false, getGreaterThanMaximumKey(), false).size());
+    assertEquals(0, map.subMap(keys[0], false, keys[1], false).size());
+    assertEquals(2, map.subMap(keys[0], true, getGreaterThanMaximumKey(), false).size());
+    assertEquals(1, map.subMap(keys[0], true, keys[1], false).size());
+    assertEquals(2, map.subMap(keys[0], true, getGreaterThanMaximumKey(), true).size());
+    assertEquals(2, map.subMap(keys[0], true, keys[1], true).size());
   }
 
   public void testSubMap_empty() {
@@ -3320,9 +3296,7 @@
     assertTrue(map.containsKey(keys[0]));
   }
 
-  /**
-   * Test method for 'java.lang.Object.toString()'.
-   */
+  /** Test method for 'java.lang.Object.toString()'. */
   public void testToString() {
     K[] keys = getKeys();
     V[] values = getValues();
diff --git a/user/test/com/google/gwt/emultest/java/util/TreeSetTest.java b/user/test/com/google/gwt/emultest/java/util/TreeSetTest.java
index 87a76d5..4b5ab8c 100644
--- a/user/test/com/google/gwt/emultest/java/util/TreeSetTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/TreeSetTest.java
@@ -16,9 +16,6 @@
 package com.google.gwt.emultest.java.util;
 
 import com.google.gwt.testing.TestUtils;
-
-import org.apache.commons.collections.TestSet;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -35,13 +32,12 @@
 /**
  * Tests <code>TreeSet</code>.
  *
- * @param <E> The key type for the underlying TreeSet
+ * <p>TODO(jat): this whole structure needs work. Ideally we would port a new Apache collections
+ * test to GWT, but that is not an insignificant amount of work.
  *
- * TODO(jat): this whole structure needs work. Ideally we would port a new
- * Apache collections test to GWT, but that is not an insignificant amount of
- * work.
+ * @param <E> The key type for the underlying TreeSet
  */
-public abstract class TreeSetTest<E extends Comparable<E>> extends TestSet {
+abstract class TreeSetTest<E extends Comparable<E>> extends TestSet {
 
   /**
    * Verify a Set is explicitly and implicitly empty.
@@ -55,15 +51,13 @@
   }
 
   /**
-   * Verify that two Collections are deeply equivalent. Some of the Sets that
-   * need to be verified do not implement a sensible equals method
-   * (TreeSet.values for example).
+   * Verify that two Collections are deeply equivalent. Some of the Sets that need to be verified do
+   * not implement a sensible equals method (TreeSet.values for example).
    *
    * @param expected
    * @param actual
    */
-  private static <T> void _assertEquals(Collection<T> expected,
-      Collection<T> actual) {
+  private static <T> void _assertEquals(Collection<T> expected, Collection<T> actual) {
     // verify equivalence using collection interface
     assertEquals(expected.isEmpty(), actual.isEmpty());
     assertEquals(expected.size(), actual.size());
@@ -83,9 +77,8 @@
    * @param expected
    * @param actual
    */
-  private static <E> void _assertEquals(SortedSet<E> expected,
-      SortedSet<E> actual) {
-    _assertEquals((Set<E>) expected, (Set<E>) actual);
+  private static <E> void _assertEquals(SortedSet<E> expected, SortedSet<E> actual) {
+    _assertEquals(expected, (Set<E>) actual);
 
     // verify the order of the associated collections
     assertEquals(expected.toArray(), actual.toArray());
@@ -105,16 +98,14 @@
     return reversedCollection;
   }
 
-  /**
-   * comparator used when creating the SortedSet.
-   */
+  /** comparator used when creating the SortedSet. */
   private Comparator<E> comparator = null;
 
-  private boolean isAddSupported = true;
-  private boolean isClearSupported = true;
-  private boolean isNullKeySupported = true;
-  private boolean isPutAllSupported = true;
-  private boolean isRemoveSupported = true;
+  private final boolean isAddSupported = true;
+  private final boolean isClearSupported = true;
+  private final boolean isNullKeySupported = true;
+  private final boolean isPutAllSupported = true;
+  private final boolean isRemoveSupported = true;
 
   public TreeSetTest() {
     super("TreeSetTest");
@@ -490,12 +481,12 @@
    * @see java.util.TreeSet#TreeSet(Comparator)
    */
   public void testConstructor_comparator() {
-    TreeSet<E> TreeSet = new TreeSet<E>(getComparator());
-    _assertEmpty(TreeSet);
+    TreeSet<E> treeSet = new TreeSet<E>(getComparator());
+    _assertEmpty(treeSet);
     if (isNaturalOrder()) {
-      assertNull(TreeSet.comparator());
+      assertNull(treeSet.comparator());
     } else {
-      assertSame(getComparator(), TreeSet.comparator());
+      assertSame(getComparator(), treeSet.comparator());
     }
   }
 
@@ -720,10 +711,10 @@
    * @see java.util.SortedSet#first()
    */
   public void testFirstKey_throwsNoSuchElementException() {
-    SortedSet<E> SortedSet = createNavigableSet();
+    SortedSet<E> sortedSet = createNavigableSet();
     // test with no entries
     try {
-      SortedSet.first();
+      sortedSet.first();
       fail("expected exception");
     } catch (NoSuchElementException e) {
       // expected outcome
@@ -781,14 +772,14 @@
    */
   @SuppressWarnings("unchecked")
   public void testHeadMap_throwsClassCastException() {
-    SortedSet SortedSet = createNavigableSet();
-    SortedSet.add(getKeys()[0]);
+    SortedSet sortedSet = createNavigableSet();
+    sortedSet.add(getKeys()[0]);
     if (isNaturalOrder()) {
       // TODO Why does this succeed with natural ordering when subSet doesn't?
-      SortedSet.headSet(getConflictingKey());
+      sortedSet.headSet(getConflictingKey());
     } else {
       try {
-        SortedSet.headSet(getConflictingKey());
+        sortedSet.headSet(getConflictingKey());
         assertTrue("CCE expected in Development Mode", !TestUtils.isJvm());
       } catch (ClassCastException e) {
         // expected outcome
@@ -891,7 +882,6 @@
    * Test method for 'java.util.Set.isEmpty()'. *
    *
    * @see java.util.Set#isEmpty()
-   *
    */
   public void testIsEmpty() {
     Set<E> sourceSet = createSet();
@@ -940,10 +930,10 @@
    * @see java.util.SortedSet#last()
    */
   public void testLastKey_throwsNoSuchElementException() {
-    SortedSet<E> SortedSet = createNavigableSet();
+    SortedSet<E> sortedSet = createNavigableSet();
     // test with no entries
     try {
-      SortedSet.last();
+      sortedSet.last();
       fail("expected exception");
     } catch (NoSuchElementException e) {
       // expected outcome
@@ -1102,10 +1092,10 @@
    */
   @SuppressWarnings("unchecked")
   public void testSubMap_throwsClassCastException() {
-    SortedSet SortedSet = createNavigableSet();
-    SortedSet.add(getKeys()[0]);
+    SortedSet sortedSet = createNavigableSet();
+    sortedSet.add(getKeys()[0]);
     try {
-      SortedSet.subSet(getConflictingKey(), getKeys()[0]);
+      sortedSet.subSet(getConflictingKey(), getKeys()[0]);
       assertTrue("CCE expected in Development Mode", !TestUtils.isJvm());
     } catch (IllegalArgumentException e) {
       // since we can't ensure CCEs in Production Mode, we may get IAE
@@ -1114,7 +1104,7 @@
       // expected outcome
     }
     try {
-      SortedSet.subSet(getKeys()[0], getConflictingKey());
+      sortedSet.subSet(getKeys()[0], getConflictingKey());
       assertTrue("CCE expected in Development Mode", !TestUtils.isJvm());
     } catch (IllegalArgumentException e) {
       // since we can't ensure CCEs in Production Mode, we may get IAE
@@ -1130,9 +1120,9 @@
    * @see java.util.SortedSet#subSet(Object, Object)
    */
   public void testSubMap_throwsIllegalArgumentException() {
-    SortedSet<E> SortedSet = createNavigableSet();
+    SortedSet<E> sortedSet = createNavigableSet();
     try {
-      SortedSet.subSet(getGreaterThanMaximumKey(), getLessThanMinimumKey());
+      sortedSet.subSet(getGreaterThanMaximumKey(), getLessThanMinimumKey());
       fail("expected exception");
     } catch (IllegalArgumentException e) {
       // from key is greater than the to key
@@ -1160,65 +1150,62 @@
     sortedSet.add(getKeys()[0]);
     assertEquals(0, sortedSet.subSet(getKeys()[0], getKeys()[0]).size());
     // bounded by a "wide" range
-    assertEquals(1, sortedSet.subSet(getLessThanMinimumKey(),
-        getGreaterThanMaximumKey()).size());
-    assertEquals(1, sortedSet.subSet(getLessThanMinimumKey(), false,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, sortedSet.subSet(getLessThanMinimumKey(), true,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, sortedSet.subSet(getLessThanMinimumKey(), false,
-        getGreaterThanMaximumKey(), true).size());
-    assertEquals(1, sortedSet.subSet(getLessThanMinimumKey(), true,
-        getGreaterThanMaximumKey(), true).size());
+    assertEquals(1, sortedSet.subSet(getLessThanMinimumKey(), getGreaterThanMaximumKey()).size());
+    assertEquals(
+        1,
+        sortedSet.subSet(getLessThanMinimumKey(), false, getGreaterThanMaximumKey(), false).size());
+    assertEquals(
+        1,
+        sortedSet.subSet(getLessThanMinimumKey(), true, getGreaterThanMaximumKey(), false).size());
+    assertEquals(
+        1,
+        sortedSet.subSet(getLessThanMinimumKey(), false, getGreaterThanMaximumKey(), true).size());
+    assertEquals(
+        1,
+        sortedSet.subSet(getLessThanMinimumKey(), true, getGreaterThanMaximumKey(), true).size());
 
     // test with two entry set
     sortedSet.add(getKeys()[1]);
 
     assertEquals(1, sortedSet.subSet(getKeys()[0], getKeys()[1]).size());
-    assertEquals(getKeys()[0],
-        sortedSet.subSet(getKeys()[0], getKeys()[1]).toArray()[0]);
+    assertEquals(getKeys()[0], sortedSet.subSet(getKeys()[0], getKeys()[1]).toArray()[0]);
 
     assertEquals(0, sortedSet.subSet(getKeys()[0], false, getKeys()[1], false).size());
 
     assertEquals(1, sortedSet.subSet(getKeys()[0], false, getKeys()[1], true).size());
-    assertEquals(getKeys()[1], sortedSet.subSet(getKeys()[0], false,
-        getKeys()[1], true).toArray()[0]);
+    assertEquals(
+        getKeys()[1], sortedSet.subSet(getKeys()[0], false, getKeys()[1], true).toArray()[0]);
 
     assertEquals(1, sortedSet.subSet(getKeys()[0], true, getKeys()[1], false).size());
-    assertEquals(getKeys()[0], sortedSet.subSet(getKeys()[0], true,
-        getKeys()[1], false).toArray()[0]);
+    assertEquals(
+        getKeys()[0], sortedSet.subSet(getKeys()[0], true, getKeys()[1], false).toArray()[0]);
 
     assertEquals(2, sortedSet.subSet(getKeys()[0], true, getKeys()[1], true).size());
-    assertEquals(getKeys()[0], sortedSet.subSet(getKeys()[0], true,
-        getKeys()[1], true).toArray()[0]);
-    assertEquals(getKeys()[1], sortedSet.subSet(getKeys()[0], true,
-        getKeys()[1], true).toArray()[1]);
+    assertEquals(
+        getKeys()[0], sortedSet.subSet(getKeys()[0], true, getKeys()[1], true).toArray()[0]);
+    assertEquals(
+        getKeys()[1], sortedSet.subSet(getKeys()[0], true, getKeys()[1], true).toArray()[1]);
 
     // bounded by a "wide" range
-    SortedSet<E> subSet = sortedSet.subSet(getLessThanMinimumKey(),
-        getGreaterThanMaximumKey());
+    SortedSet<E> subSet = sortedSet.subSet(getLessThanMinimumKey(), getGreaterThanMaximumKey());
 
     assertEquals(2, subSet.size());
 
-    assertEquals(2, sortedSet.subSet(getLessThanMinimumKey(), false,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, sortedSet.subSet(getKeys()[0], false,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(0, sortedSet.subSet(getKeys()[0], false,
-        getKeys()[1], false).size());
-    assertEquals(2, sortedSet.subSet(getKeys()[0], true,
-        getGreaterThanMaximumKey(), false).size());
-    assertEquals(1, sortedSet.subSet(getKeys()[0], true,
-        getKeys()[1], false).size());
-    assertEquals(2, sortedSet.subSet(getKeys()[0], true,
-        getGreaterThanMaximumKey(), true).size());
-    assertEquals(2, sortedSet.subSet(getKeys()[0], true,
-        getKeys()[1], true).size());
+    assertEquals(
+        2,
+        sortedSet.subSet(getLessThanMinimumKey(), false, getGreaterThanMaximumKey(), false).size());
+    assertEquals(
+        1, sortedSet.subSet(getKeys()[0], false, getGreaterThanMaximumKey(), false).size());
+    assertEquals(0, sortedSet.subSet(getKeys()[0], false, getKeys()[1], false).size());
+    assertEquals(2, sortedSet.subSet(getKeys()[0], true, getGreaterThanMaximumKey(), false).size());
+    assertEquals(1, sortedSet.subSet(getKeys()[0], true, getKeys()[1], false).size());
+    assertEquals(2, sortedSet.subSet(getKeys()[0], true, getGreaterThanMaximumKey(), true).size());
+    assertEquals(2, sortedSet.subSet(getKeys()[0], true, getKeys()[1], true).size());
   }
 
   /**
-   * Test method for 'java.util.SortedSet.tailSet(Object)' and
-   * '@see java.util.NavigableSet.tailSet(Object, boolean)'.
+   * Test method for 'java.util.SortedSet.tailSet(Object)' and '@see
+   * java.util.NavigableSet.tailSet(Object, boolean)'.
    *
    * @see java.util.SortedSet#tailSet(Object)
    * @see java.util.NavigableSet#tailSet(Object, boolean)
@@ -1233,8 +1220,8 @@
   }
 
   /**
-   * Test method for 'java.util.SortedSet.tailSet(Object)' and
-   * '@see java.util.NavigableSet.tailSet(Object, boolean)'.
+   * Test method for 'java.util.SortedSet.tailSet(Object)' and '@see
+   * java.util.NavigableSet.tailSet(Object, boolean)'.
    *
    * @see java.util.SortedSet#tailSet(Object)
    * @see java.util.NavigableSet#tailSet(Object, boolean)
@@ -1257,8 +1244,8 @@
   }
 
   /**
-   * Test method for 'java.util.SortedSet.tailSet(Object)' and
-   * '@see java.util.NavigableSet.tailSet(Object, boolean)'.
+   * Test method for 'java.util.SortedSet.tailSet(Object)' and '@see
+   * java.util.NavigableSet.tailSet(Object, boolean)'.
    *
    * @see java.util.SortedSet#tailSet(Object)
    * @see java.util.NavigableSet#tailSet(Object, boolean)
@@ -1282,8 +1269,8 @@
   }
 
   /**
-   * Test method for 'java.util.SortedSet.tailSet(Object)' and
-   * '@see java.util.NavigableSet.tailSet(Object, boolean)'.
+   * Test method for 'java.util.SortedSet.tailSet(Object)' and '@see
+   * java.util.NavigableSet.tailSet(Object, boolean)'.
    *
    * @see java.util.SortedSet#tailSet(Object)
    * @see java.util.NavigableSet#tailSet(Object, boolean)
@@ -1333,14 +1320,14 @@
    */
   @SuppressWarnings("unchecked")
   public void testTailSet_throwsClassCastException() {
-    SortedSet SortedSet = createNavigableSet();
-    SortedSet.add(getKeys()[0]);
+    SortedSet sortedSet = createNavigableSet();
+    sortedSet.add(getKeys()[0]);
     if (isNaturalOrder()) {
       // TODO Why does this succeed with natural ordering when subSet doesn't?
-      SortedSet.tailSet(getConflictingKey());
+      sortedSet.tailSet(getConflictingKey());
     } else {
       try {
-        SortedSet.tailSet(getConflictingKey());
+        sortedSet.tailSet(getConflictingKey());
         assertTrue("CCE expected in Development Mode", !TestUtils.isJvm());
       } catch (ClassCastException e) {
         // expected outcome
@@ -1384,7 +1371,6 @@
     return comparator == null;
   }
 
-  @SuppressWarnings("unchecked")
   @Override
   protected Set makeEmptySet() {
     return createTreeSet();
diff --git a/user/test/org/apache/commons/Collections.gwt.xml b/user/test/org/apache/commons/Collections.gwt.xml
deleted file mode 100644
index 0c36542..0000000
--- a/user/test/org/apache/commons/Collections.gwt.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!--                                                                        -->
-<!-- Copyright 2007 Google Inc.                                             -->
-<!-- Licensed under the Apache License, Version 2.0 (the "License"); you    -->
-<!-- may not use this file except in compliance with the License. You may   -->
-<!-- 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. License for the specific language governing permissions and   -->
-<!-- limitations under the License.                                         -->
-
-<module>
-	<inherits name='com.google.gwt.junit.JUnit'/>
- 	<source path='collections'/>
-</module>
diff --git a/user/test/org/apache/commons/collections/DefaultMapEntry.java b/user/test/org/apache/commons/collections/DefaultMapEntry.java
deleted file mode 100644
index f6daecc..0000000
--- a/user/test/org/apache/commons/collections/DefaultMapEntry.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-import java.util.Map;
-
-/** A default implementation of {@link java.util.Map.Entry}
-  *
-  * @since 1.0
-  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
-  * @author <a href="mailto:mas@apache.org">Michael A. Smith</a>
-  */
-@SuppressWarnings({"unchecked", "rawtypes"})
-public class DefaultMapEntry implements Map.Entry {
-    
-    private Object key;
-    private Object value;
-    
-    /**
-     *  Constructs a new <Code>DefaultMapEntry</Code> with a null key
-     *  and null value.
-     */
-    public DefaultMapEntry() {
-    }
-
-    /**
-     *  Constructs a new <Code>DefaultMapEntry</Code> with the given
-     *  key and given value.
-     *
-     *  @param key  the key for the entry, may be null
-     *  @param value  the value for the entyr, may be null
-     */
-    public DefaultMapEntry(Object key, Object value) {
-        this.key = key;
-        this.value = value;
-    }
-
-    /**
-     *  Implemented per API documentation of 
-     *  {@link java.util.Map.Entry#equals(Object)}
-     **/
-    @Override
-    public boolean equals(Object o) {
-        if( o == null ) return false;
-        if( o == this ) return true;        
-
-        if ( ! (o instanceof Map.Entry ) )
-            return false;
-        Map.Entry e2 = (Map.Entry)o;    
-        return ((getKey() == null ?
-                 e2.getKey() == null : getKey().equals(e2.getKey())) &&
-                (getValue() == null ?
-                 e2.getValue() == null : getValue().equals(e2.getValue())));
-    }
-     
-     
-    /**
-     *  Implemented per API documentation of 
-     *  {@link java.util.Map.Entry#hashCode()}
-     **/
-    @Override
-    public int hashCode() {
-        return ( ( getKey() == null ? 0 : getKey().hashCode() ) ^
-                 ( getValue() == null ? 0 : getValue().hashCode() ) ); 
-    }
-    
-
-
-    // Map.Entry interface
-    //-------------------------------------------------------------------------
-
-    /**
-     *  Returns the key.
-     *
-     *  @return the key 
-     */
-    @Override
-    public Object getKey() {
-        return key;
-    }
-
-
-    /**
-     *  Returns the value.
-     *
-     *  @return the value
-     */
-    @Override
-    public Object getValue() {
-        return value;
-    }
-
-    // Properties
-    //-------------------------------------------------------------------------    
-
-    /**
-     *  Sets the key.  This method does not modify any map.
-     *
-     *  @param key  the new key
-     */
-    public void setKey(Object key) {
-        this.key = key;
-    }
-    
-    /** Note that this method only sets the local reference inside this object and
-      * does not modify the original Map.
-      *
-      * @return the old value of the value
-      * @param value the new value
-      */
-    @Override
-    public Object setValue(Object value) {
-        Object answer = this.value;
-        this.value = value;
-        return answer;
-    }
-
-}
diff --git a/user/test/org/apache/commons/collections/LocalTestNode.java b/user/test/org/apache/commons/collections/LocalTestNode.java
deleted file mode 100644
index e141975..0000000
--- a/user/test/org/apache/commons/collections/LocalTestNode.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-/**
-* Class LocalTestNode
-*
-* a helper class for TestDoubleOrderedMap
-*
-* @author Marc Johnson (marcj at users dot sourceforge dot net)
-*/
-@SuppressWarnings({"unchecked", "rawtypes"})
-class LocalTestNode implements Comparable {
-
-    private Comparable key;
-    private Comparable value;
-
-    /**
-     * construct a LocalTestNode
-     *
-     * @param key value used to create the key and value
-     */
-    LocalTestNode(final int key) {
-        this.key   = new Integer(key);
-        this.value = String.valueOf(key);
-    }
-
-    /**
-     * @param key the unique key associated with the current node.
-     */
-    void setKey(Comparable key) {
-        this.key = key;
-    }
-
-    /**
-     * Returns the unique key associated with the current node.
-     */
-    Comparable getKey() {
-        return key;
-    }
-
-    /**
-     * @param value the unique value associated with the current node.
-     */
-    void setValue(Comparable value) {
-        this.value = value;
-    }
-
-    /**
-     * Returns the unique value associated with the current node.
-     */
-    Comparable getValue() {
-        return value;
-    }
-
-    /**
-     * Method compareTo
-     *
-     * @param o
-     *
-     * @return int
-     */
-    @Override
-    public int compareTo(Object o) {
-
-        LocalTestNode other = (LocalTestNode) o;
-        int           rval  = getKey().compareTo(other.getKey());
-
-        if (rval == 0) {
-            rval = getValue().compareTo(other.getValue());
-        }
-
-        return rval;
-    }
-
-    /**
-     * Method equals
-     *
-     * @param o
-     *
-     * @return true if equal
-     */
-    @Override
-    public boolean equals(Object o) {
-
-        if (o == null) {
-            return false;
-        }
-
-
-        if(!(getClass().getName().equals(o.getClass().getName()))){
-            return false;
-        }
-        LocalTestNode node = (LocalTestNode) o;
-
-        return (getKey().equals(node.getKey())
-                && getValue().equals(node.getValue()));
-    }
-
-    /**
-     * @return hash code
-     */
-    @Override
-    public int hashCode() {
-        return getKey().hashCode() ^ getValue().hashCode();
-    }
-}
diff --git a/user/test/org/apache/commons/collections/TestCollection.java b/user/test/org/apache/commons/collections/TestCollection.java
deleted file mode 100644
index f1333f0..0000000
--- a/user/test/org/apache/commons/collections/TestCollection.java
+++ /dev/null
@@ -1,1058 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-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 #isAddSuppoted()}
- * <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.
- *
- * 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>
- *
- * @author Rodney Waldhoff
- * @author Paul Jack
- * @author <a href="mailto:mas@apache.org">Michael A. Smith</a>
- * @version $Id: TestCollection.java,v 1.9.2.1 2004/05/22 12:14:05 scolebourne Exp $
- */
-@SuppressWarnings({"unchecked", "rawtypes"})
-public 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 heterogenous 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 heterogenous 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++) {
-            assertTrue("Empty collection shouldn'y 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'y 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[] {
-            new String(""),
-            new String("One"),
-            new Integer(2),
-            "Three",
-            new Integer(4),
-            "One",
-            new Double(5),
-            new Float(6),
-            "Seven",
-            "Eight",
-            new String("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
-     *  heterogenous 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
-     *  heterogenous 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"
-        };
-    }
-}
diff --git a/user/test/org/apache/commons/collections/TestComparator.java b/user/test/org/apache/commons/collections/TestComparator.java
deleted file mode 100644
index 8e3025e..0000000
--- a/user/test/org/apache/commons/collections/TestComparator.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-@SuppressWarnings({"unchecked", "rawtypes"})
-public abstract class TestComparator extends TestObject {
- 
-
-    public abstract Comparator makeComparator();
-    public abstract List getComparableObjectsOrdered();
-
-    @Override
-    public Object makeObject() {
-        return makeComparator();
-    }
-
-    /**
-     * There were no Comparators in version 1.x.
-     * 
-     * @return 2
-     */
-    @Override
-    public int getCompatibilityVersion() {
-        return 2;
-    }
-
-    public void reverseObjects(List list) {
-        Collections.reverse(list);
-    }
-
-     
-
-    /**
-     * Sort object according to the given Comparator.
-     * 
-     * @param list       List to sort
-     * @param comparator sorting comparator
-     */
-    public void sortObjects(List list, Comparator comparator) {
-
-        Collections.sort(list,comparator);
-
-    }
-
-    @Override
-    public boolean supportsEmptyCollections() {
-        return false;
-    }
-
-    @Override
-    public boolean supportsFullCollections() {
-        return false;
-    }
-
-    public void testEmptyListSort() {
-        List list = new ArrayList();
-        sortObjects(list,makeComparator());
-
-        List list2 = new ArrayList();
-        
-        assertTrue("Comparator cannot sort empty lists",
-                   list2.equals(list));
-    }
-
-    public void testReverseListSort() {
-        Comparator comparator = makeComparator();
-
-        List randomList = getComparableObjectsOrdered();
-        reverseObjects(randomList);
-        sortObjects(randomList,comparator);
-
-        List orderedList = getComparableObjectsOrdered();
-
-        assertTrue("Comparator did not reorder the List correctly",
-                   orderedList.equals(randomList));
-
-    }
-
-     
-    
-
-    public String getCanonicalComparatorName(Object object) {
-        StringBuffer retval = new StringBuffer();
-        retval.append("data/test/");
-        String colName = object.getClass().getName();
-        colName = colName.substring(colName.lastIndexOf(".")+1,colName.length());
-        retval.append(colName);
-        retval.append(".version");
-        retval.append(getCompatibilityVersion());
-        retval.append(".obj");
-        return retval.toString();
-    }
-
-    /**
-     * Compare the current serialized form of the Comparator
-     * against the canonical version in CVS.
-     */
-    public void testComparatorCompatibility() {
-        Comparator comparator = null;
-
-        
-        // make sure the canonical form produces the ordering we currently
-        // expect
-        List randomList = getComparableObjectsOrdered();
-        reverseObjects(randomList);
-        sortObjects(randomList,comparator);
-
-        List orderedList = getComparableObjectsOrdered();
-
-        assertTrue("Comparator did not reorder the List correctly:" + randomList,
-                   orderedList.equals(randomList));
-    }
-
-}
diff --git a/user/test/org/apache/commons/collections/TestIterator.java b/user/test/org/apache/commons/collections/TestIterator.java
deleted file mode 100644
index 4714bc1..0000000
--- a/user/test/org/apache/commons/collections/TestIterator.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Base class for tetsing Iterator interface
- * 
- * @author Morgan Delagrange
- */
-@SuppressWarnings({"unchecked", "rawtypes"})
-public abstract class TestIterator extends TestObject {
-
-   
-
-    public abstract Iterator makeEmptyIterator();
-
-    public abstract Iterator makeFullIterator();
-
-    /**
-     * Whether or not we are testing an iterator that can be
-     * empty.  Default is true.
-     * 
-     * @return true if Iterators can be empty
-     */
-    public boolean supportsEmptyIterator() {
-        return true;
-    }
-
-    /**
-     * Whether or not we are testing an iterator that can contain
-     * elements.  Default is true.
-     * 
-     * @return true if Iterators can be empty
-     */
-    public boolean supportsFullIterator() {
-        return true;
-    }
-
-    /**
-     * Whether or not we are testing an iterator that supports remove.  
-     * Default is true.
-     * 
-     * @return true if Iterators can remove elements
-     */
-    public boolean supportsRemove() {
-        return true;
-    }
-    
-    /**
-     * Should throw a NoSuchElementException.
-     */
-    public void testEmptyIterator() {
-        if (supportsEmptyIterator() == false) {
-            return;
-        }
-
-        Iterator iter = makeEmptyIterator();
-        assertTrue("hasNext() should return false for empty iterators",iter.hasNext() == false);
-        try {
-	    iter.next();
-            fail("NoSuchElementException must be thrown when Iterator is exhausted");
-	} catch (NoSuchElementException e) {
-	}
-    }
-
-    /**
-     * NoSuchElementException (or any other exception)
-     * should not be thrown for the first element.  
-     * NoSuchElementException must be thrown when
-     * hasNext() returns false
-     */
-    public void testFullIterator() {
-        if (supportsFullIterator() == false) {
-            return;
-        }
-
-        Iterator iter = makeFullIterator();
-
-        assertTrue("hasNext() should return true for at least one element",iter.hasNext());
-
-        try {
-	    iter.next();
-	} catch (NoSuchElementException e) {
-            fail("Full iterators must have at least one element");
-	}
-
-        while (iter.hasNext()) {
-            iter.next();
-        }
-
-        try {
-	    iter.next();
-            fail("NoSuchElementException must be thrown when Iterator is exhausted");
-	} catch (NoSuchElementException e) {
-	}
-    }
-
-}
diff --git a/user/test/org/apache/commons/collections/TestList.java b/user/test/org/apache/commons/collections/TestList.java
deleted file mode 100644
index e951855..0000000
--- a/user/test/org/apache/commons/collections/TestList.java
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-/**
- * Tests base {@link java.util.List} methods and contracts.
- * <p>
- * To use, simply extend this class, and implement
- * the {@link #makeList} method.
- * <p>
- * If your {@link List} fails one of these tests by design,
- * you may still use this base set of cases.  Simply override the
- * test case (method) your {@link List} fails.
- *
- * @author Rodney Waldhoff
- * @author Paul Jack
- * @version $Id: TestList.java,v 1.13.2.1 2004/05/22 12:14:05 scolebourne Exp $
- */
-@SuppressWarnings({"unchecked", "rawtypes"})
-public abstract class TestList extends TestCollection {
-
- 
-
-
-    /**
-     *  Return a new, empty {@link List} to be used for testing.
-     *
-     *  @return an empty list for testing.
-     */
-    protected abstract List makeEmptyList();
-
-
-    /**
-     *  Return a new, full {@link List} to be used for testing.
-     *
-     *  @return a full list for testing
-     */
-    protected List makeFullList() {
-        // only works if list supports optional "addAll(Collection)" 
-        List list = makeEmptyList();
-        list.addAll(Arrays.asList(getFullElements()));
-        return list;
-    }
-
-
-    /**
-     *  Returns {@link makeEmptyList()}.
-     *
-     *  @return an empty list to be used for testing
-     */
-    @Override
-    final protected Collection makeCollection() {
-        return makeEmptyList();
-    }
-
-
-    /**
-     *  Returns {@link makeFullList()}.
-     *
-     *  @return a full list to be used for testing
-     */
-    @Override
-    final protected Collection makeFullCollection() {
-        return makeFullList();
-    }
-
-
-
-    /**
-     * Whether or not we are testing an iterator that can be
-     * empty.  Default is true.
-     * 
-     * @return true if Iterators can be empty
-     */
-    public boolean supportsEmptyIterator() {
-        return true;
-    }
-
-    /**
-     * Whether or not we are testing an list that allows
-     * element set.  Default is true.
-     * 
-     * @return true if Lists support element set
-     */
-    public boolean isSetSupported() {
-        return true;
-    }
-    
-    
-    /**
-     *  Returns the {@link collection} field cast to a {@link List}.
-     *
-     *  @return the collection field as a List
-     */
-    protected List getList() {
-        return (List)collection;
-    } 
-
-
-    /**
-     *  Returns the {@link confirmed} field cast to a {@link List}.
-     *
-     *  @return the confirmed field as a List
-     */
-    protected List getConfirmedList() {
-        return (List)confirmed;
-    }
-
-
-  
-
-      public class TestListIterator extends AbstractTestListIterator {
-
-        @Override
-        public Object addSetValue() {
-          return TestList.this.getOtherElements()[0];
-        }
-
-        @Override
-        public boolean supportsRemove() {
-          return TestList.this.isRemoveSupported();
-        }
-
-        @Override
-        public boolean supportsAdd() {
-          return TestList.this.isAddSupported();
-        }
-
-        @Override
-        public boolean supportsSet() {
-          return TestList.this.isSetSupported();
-        }
-
-        @Override
-        public ListIterator makeEmptyListIterator() {
-          resetEmpty();
-          return ((List) TestList.this.collection).listIterator();
-        }
-
-        @Override
-        public ListIterator makeFullListIterator() {
-          resetFull();
-          return ((List) TestList.this.collection).listIterator();
-        }
-
-        @Override
-        public Object makeObject() {
-          return ((List) TestList.this.collection).listIterator();
-        }
-      }
-
-      /**
-       * Tests the read-only bits of {@link List#listIterator()}.
-       */
-      public void testListListIterator() {
-        resetFull();
-        forwardTest(getList().listIterator(), 0);
-        backwardTest(getList().listIterator(), 0);
-      }
-
-      /**
-       * Tests the read-only bits of {@link List#listIterator(int)}.
-       */
-      public void testListListIteratorByIndex() {
-        resetFull();
-        try {
-          getList().listIterator(-1);
-        } catch (IndexOutOfBoundsException ex) {
-        }
-        resetFull();
-        try {
-          getList().listIterator(getList().size() + 1);
-        } catch (IndexOutOfBoundsException ex) {
-        }
-        resetFull();
-        for (int i = 0; i <= confirmed.size(); i++) {
-          forwardTest(getList().listIterator(i), i);
-          backwardTest(getList().listIterator(i), i);
-        }
-        resetFull();
-        for (int i = 0; i <= confirmed.size(); i++) {
-          backwardTest(getList().listIterator(i), i);
-        }
-      }
-
-      // -----------------------------------------------------------------------
-      /**
-       * Tests remove on list iterator is correct.
-       */
-      public void testListListIteratorPreviousRemoveNext() {
-        if (isRemoveSupported() == false)
-          return;
-        resetFull();
-        if (collection.size() < 4)
-          return;
-        ListIterator it = getList().listIterator();
-        Object zero = it.next();
-        Object one = it.next();
-        Object two = it.next();
-        Object two2 = it.previous();
-        Object one2 = it.previous();
-        assertEquals(one, one2);
-        assertEquals(two, two2);
-        assertEquals(zero, getList().get(0));
-        assertEquals(one, getList().get(1));
-        assertEquals(two, getList().get(2));
-        
-        it.remove(); // removed element at index 1 (one)
-        assertEquals(zero, getList().get(0));
-        assertEquals(two, getList().get(1));
-        Object two3 = it.next(); // do next after remove
-        assertEquals(two, two3);
-        assertEquals(collection.size() > 2, it.hasNext());
-        assertEquals(true, it.hasPrevious());
-      }
-
-      /**
-       * Tests remove on list iterator is correct.
-       */
-      public void testListListIteratorPreviousRemovePrevious() {
-        if (isRemoveSupported() == false)
-          return;
-        resetFull();
-        if (collection.size() < 4)
-          return;
-        ListIterator it = getList().listIterator();
-        Object zero = it.next();
-        Object one = it.next();
-        Object two = it.next();
-        Object two2 = it.previous();
-        Object one2 = it.previous();
-        assertEquals(one, one2);
-        assertEquals(two, two2);
-        assertEquals(zero, getList().get(0));
-        assertEquals(one, getList().get(1));
-        assertEquals(two, getList().get(2));
-
-        it.remove(); // removed element at index 1 (one)
-        assertEquals(zero, getList().get(0));
-        assertEquals(two, getList().get(1));
-        Object zero3 = it.previous(); // do previous after remove
-        assertEquals(zero, zero3);
-        assertEquals(false, it.hasPrevious());
-        assertEquals(collection.size() > 2, it.hasNext());
-      }
-
-      /**
-       * Tests remove on list iterator is correct.
-       */
-      public void testListListIteratorNextRemoveNext() {
-        if (isRemoveSupported() == false)
-          return;
-        resetFull();
-        if (collection.size() < 4)
-          return;
-        ListIterator it = getList().listIterator();
-        Object zero = it.next();
-        Object one = it.next();
-        Object two = it.next();
-        assertEquals(zero, getList().get(0));
-        assertEquals(one, getList().get(1));
-        assertEquals(two, getList().get(2));
-        Object three = getList().get(3);
-
-        it.remove(); // removed element at index 2 (two)
-        assertEquals(zero, getList().get(0));
-        assertEquals(one, getList().get(1));
-        Object three2 = it.next(); // do next after remove
-        assertEquals(three, three2);
-        assertEquals(collection.size() > 3, it.hasNext());
-        assertEquals(true, it.hasPrevious());
-      }
-
-      /**
-       * Tests remove on list iterator is correct.
-       */
-      public void testListListIteratorNextRemovePrevious() {
-        if (isRemoveSupported() == false)
-          return;
-        resetFull();
-        if (collection.size() < 4)
-          return;
-        ListIterator it = getList().listIterator();
-        Object zero = it.next();
-        Object one = it.next();
-        Object two = it.next();
-        assertEquals(zero, getList().get(0));
-        assertEquals(one, getList().get(1));
-        assertEquals(two, getList().get(2));
-
-        it.remove(); // removed element at index 2 (two)
-        assertEquals(zero, getList().get(0));
-        assertEquals(one, getList().get(1));
-        Object one2 = it.previous(); // do previous after remove
-        assertEquals(one, one2);
-        assertEquals(true, it.hasNext());
-        assertEquals(true, it.hasPrevious());
-      }
-
-      // -----------------------------------------------------------------------
-      /**
-       * Traverses to the end of the given iterator.
-       * 
-       * @param iter the iterator to traverse
-       * @param i the starting index
-       */
-      private void forwardTest(ListIterator iter, int i) {
-        List list = getList();
-        int max = getFullElements().length;
-
-        while (i < max) {
-          assertTrue("Iterator should have next", iter.hasNext());
-          assertEquals("Iterator.nextIndex should work", iter.nextIndex(), i);
-          assertEquals("Iterator.previousIndex should work", iter.previousIndex(),
-              i - 1);
-          Object o = iter.next();
-          assertEquals("Iterator returned correct element f", list.get(i), o);
-          i++;
-        }
-
-        assertTrue("Iterator shouldn't have next", !iter.hasNext());
-        assertEquals("nextIndex should be size", iter.nextIndex(), max);
-        assertEquals("previousIndex should be size - 1", iter.previousIndex(),
-            max - 1);
-
-        try {
-          iter.next();
-          fail("Exhausted iterator should raise NoSuchElement");
-        } catch (NoSuchElementException e) {
-          // expected
-        }
-      }
-
-      /**
-       * Traverses to the beginning of the given iterator.
-       * 
-       * @param iter the iterator to traverse
-       * @param i the starting index
-       */
-      private void backwardTest(ListIterator iter, int i) {
-        List list = getList();
-
-        while (i > 0) {
-          assertTrue("Iterator should have previous, i:" + i, iter.hasPrevious());
-          assertEquals("Iterator.nextIndex should work, i:" + i, iter.nextIndex(),
-              i);
-          assertEquals("Iterator.previousIndex should work, i:" + i,
-              iter.previousIndex(), i - 1);
-          Object o = iter.previous();
-          assertEquals("Iterator returned correct element b", list.get(i - 1), o);
-          i--;
-        }
-
-        assertTrue("Iterator shouldn't have previous", !iter.hasPrevious());
-        int nextIndex = iter.nextIndex();
-    assertEquals("nextIndex should be 0, actual value: " + nextIndex, 0, nextIndex);
-        int prevIndex = iter.previousIndex();
-    assertEquals("previousIndex should be -1, actual value: " + prevIndex, -1, prevIndex);
-
-        try {
-          iter.previous();
-          fail("Exhausted iterator should raise NoSuchElement");
-        } catch (NoSuchElementException e) {
-          // expected
-        }
-
-      }
-
-      /**
-       * Tests the {@link ListIterator#add(Object)} method of the list iterator.
-       */
-      public void testListIteratorAdd() {
-        if (!isAddSupported())
-          return;
-
-        resetEmpty();
-        List list1 = getList();
-        List list2 = getConfirmedList();
-
-        Object[] elements = getFullElements();
-        ListIterator iter1 = list1.listIterator();
-        ListIterator iter2 = list2.listIterator();
-
-        for (int i = 0; i < elements.length; i++) {
-          iter1.add(elements[i]);
-          iter2.add(elements[i]);
-          verify();
-        }
-
-        resetFull();
-        iter1 = getList().listIterator();
-        iter2 = getConfirmedList().listIterator();
-        for (int i = 0; i < elements.length; i++) {
-          iter1.next();
-          iter2.next();
-          iter1.add(elements[i]);
-          iter2.add(elements[i]);
-          verify();
-        }
-      }
-
-      /**
-       * Tests the {@link ListIterator#set(Object)} method of the list iterator.
-       */
-      public void testListIteratorSet() {
-        if (!isSetSupported())
-          return;
-
-        Object[] elements = getFullElements();
-
-        resetFull();
-        ListIterator iter1 = getList().listIterator();
-        ListIterator iter2 = getConfirmedList().listIterator();
-        for (int i = 0; i < elements.length; i++) {
-          iter1.next();
-          iter2.next();
-          iter1.set(elements[i]);
-          iter2.set(elements[i]);
-          verify();
-        }
-      }
-
-      
-      
-      
-    /**
-     *  Tests {@link List#add(int,Object)}.
-     */
-    public void testListAddByIndex() {
-        if (!isAddSupported()) return;
-
-        Object element = getOtherElements()[0];
-        int max = getFullElements().length;
-
-        for (int i = 0; i <= max; i++) {
-            resetFull();
-            ((List)collection).add(i, element);
-            ((List)confirmed).add(i, element);
-            verify();
-        }
-    }
-
-
-    /**
-     *  Tests {@link List#equals(Object)}.
-     */
-    public void testListEquals() {
-        resetEmpty();
-        List list = getList();
-        assertTrue("Empty lists should be equal", list.equals(confirmed));
-        verify();
-        assertTrue("Empty list should equal self", list.equals(list));
-        verify();
-
-        List list2 = Arrays.asList(getFullElements());
-        assertTrue("Empty list shouldn't equal full", !list.equals(list2));
-        verify();
-
-        list2 = Arrays.asList(getOtherElements());
-        assertTrue("Empty list shouldn't equal other", !list.equals(list2));
-        verify();
-
-        resetFull();
-        list = getList();
-        assertTrue("Full lists should be equal", list.equals(confirmed));
-        verify();
-        assertTrue("Full list should equal self", list.equals(list));
-        verify();
-
-        list2 = makeEmptyList();
-        assertTrue("Full list shouldn't equal empty", !list.equals(list2));
-        verify();
-
-        list2 = Arrays.asList(getOtherElements());
-        assertTrue("Full list shouldn't equal other", !list.equals(list2));
-        verify();
-
-        list2 = Arrays.asList(getFullElements());
-        Collections.reverse(list2);
-        assertTrue("Full list shouldn't equal full list with same elements" +
-          " but different order", !list.equals(list2));
-        verify();
-
-        assertTrue("List shouldn't equal String", !list.equals(""));
-        verify();
-
-        final List listForC = Arrays.asList(getFullElements());
-        Collection c = new AbstractCollection() {
-            @Override
-            public int size() {
-                return listForC.size();
-            }
-
-            @Override
-            public Iterator iterator() {
-                return listForC.iterator();
-            }
-        };
-
-        assertTrue("List shouldn't equal nonlist with same elements " +
-          " in same order", !list.equals(c));
-        verify();
-    }
-
-
-    /**
-     *  Tests {@link List#hashCode()}.
-     */
-    public void testListHashCode() {
-        resetEmpty();
-        int hash1 = collection.hashCode();
-        int hash2 = confirmed.hashCode();
-        assertEquals("Empty lists should have equal hashCodes", hash1, hash2);
-        verify();
-
-        resetFull();
-        hash1 = collection.hashCode();
-        hash2 = confirmed.hashCode();
-        assertEquals("Full lists should have equal hashCodes", hash1, hash2);
-        verify();
-    }
-
-
-    /**
-     *  Tests {@link List#get(int)}.
-     */
-    public void testListGetByIndex() {
-        resetFull();
-        List list = getList();
-        Object[] elements = getFullElements();
-        for (int i = 0; i < elements.length; i++) {
-            assertEquals("List should contain correct elements", 
-              elements[i], list.get(i));
-            verify();
-        }
-    }
-
-
-     
-    /**
-     *  Tests {@link List#indexOf()}.
-     */
-    public void testListIndexOf() {
-        resetFull();
-        List list1 = getList();
-        List list2 = getConfirmedList();
-
-        Iterator iterator = list2.iterator();
-        while (iterator.hasNext()) {
-            Object element = iterator.next();
-            assertEquals("indexOf should return correct result", 
-              list1.indexOf(element), list2.indexOf(element));            
-            verify();
-        }
-
-        Object[] other = getOtherElements();
-        for (int i = 0; i < other.length; i++) {
-      assertEquals("indexOf should return -1 for nonexistent element", -1, list1.indexOf(other[i]));
-            verify();
-        }
-    }
-
-
-    /**
-     *  Tests {@link List#lastIndexOf()}.
-     */
-    public void testListLastIndexOf() {
-        resetFull();
-        List list1 = getList();
-        List list2 = getConfirmedList();
-
-        Iterator iterator = list2.iterator();
-        while (iterator.hasNext()) {
-            Object element = iterator.next();
-            assertEquals("lastIndexOf should return correct result",
-              list1.lastIndexOf(element), list2.lastIndexOf(element));
-            verify();
-        }
-
-        Object[] other = getOtherElements();
-        for (int i = 0; i < other.length; i++) {
-      assertEquals(
-          "lastIndexOf should return -1 for nonexistent " + "element",
-          -1,
-          list1.lastIndexOf(other[i]));
-            verify();
-        }
-    }
-
-
-     
-
-    /**
-     *  Tests {@link List#remove(int)}.
-     */
-    public void testListRemoveByIndex() {
-        if (!isRemoveSupported()) return;
-
-        int max = getFullElements().length;
-        for (int i = 0; i < max; i++) {
-            resetFull();
-            Object o1 = ((List)collection).remove(i);
-            Object o2 = ((List)confirmed).remove(i);
-            assertEquals("remove should return correct element", o1, o2);
-            verify();
-        }
-    }
- 
- 
-  
- 
-   
-   
-    
-
-
-    /**
-     *  Returns an empty {@link ArrayList}.
-     */
-    @Override
-    protected Collection makeConfirmedCollection() {
-        ArrayList list = new ArrayList();
-        return list;
-    }
-
-
-    /**
-     *  Returns a full {@link ArrayList}.
-     */
-    @Override
-    protected Collection makeConfirmedFullCollection() {
-        ArrayList list = new ArrayList();
-        list.addAll(Arrays.asList(getFullElements()));
-        return list;
-    }
-
-
-    /**
-     *  Verifies that the test list implementation matches the confirmed list
-     *  implementation.
-     */
-    @Override
-    protected void verify() {
-        super.verify();
-
-        List list1 = getList();
-        List list2 = getConfirmedList();
-
-        assertEquals("List should equal confirmed", list1, list2);
-        assertEquals("Confirmed should equal list", list2, list1);
-
-        assertEquals("Hash codes should be equal", 
-          list1.hashCode(), list2.hashCode());
-
-        int i = 0;
-        Iterator iterator1 = list1.iterator();
-        Iterator iterator2 = list2.iterator();
-        Object[] array = list1.toArray();
-        while (iterator2.hasNext()) {
-            assertTrue("List iterator should have next", iterator1.hasNext());
-            Object o1 = iterator1.next();
-            Object o2 = iterator2.next();
-            assertEquals("Iterator elements should be equal", o1, o2);
-            o2 = list1.get(i);
-            assertEquals("get should return correct element", o1, o2);
-            o2 = array[i];
-            assertEquals("toArray should have correct element", o1, o2);
-            i++;
-        }
-    }
-
-    
- 
-
-}
diff --git a/user/test/org/apache/commons/collections/TestMap.java b/user/test/org/apache/commons/collections/TestMap.java
deleted file mode 100644
index 1c4cf29..0000000
--- a/user/test/org/apache/commons/collections/TestMap.java
+++ /dev/null
@@ -1,1169 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-import com.google.gwt.testing.TestUtils;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import jsinterop.annotations.JsPackage;
-import jsinterop.annotations.JsProperty;
-
-/**
- * Tests base {@link java.util.Map} methods and contracts.
- * <p>
- * The forces at work here are similar to those in {@link TestCollection}.
- * If your class implements the full Map interface, including optional
- * operations, simply extend this class, and implement the {@link
- * #makeEmptyMap()} method.
- * <p>
- * On the other hand, if your map implemenation is weird, you may have to
- * override one or more of the other protected methods.  They're described
- * below.<P>
- *
- * <B>Entry Population Methods</B><P>
- *
- * Override these methods if your map requires special entries:
- *
- * <UL>
- * <LI>{@link #getSampleKeys()}
- * <LI>{@link #getSampleValues()}
- * <LI>{@link #getNewSampleValues()}
- * <LI>{@link #getOtherKeys()}
- * <LI>{@link #getOtherValues()}
- * </UL>
- *
- * <B>Supported Operation Methods</B><P>
- *
- * Override these methods if your map doesn't support certain operations:
- *
- * <UL>
- * <LI> {@link #useDuplicateValues()}
- * <LI> {@link #useNullKey()}
- * <LI> {@link #useNullValue()}
- * <LI> {@link #isAddRemoveModifiable()}
- * <LI> {@link #isChangeable()}
- * </UL>
- *
- * <B>Fixture Methods</B><P>
- *
- * For tests on modification operations (puts and removes), fixtures are used
- * to verify that that operation results in correct state for the map and its
- * collection views.  Basically, the modification is performed against your
- * map implementation, and an identical modification is performed against
- * a <I>confirmed</I> map implementation.  A confirmed map implementation is
- * something like <Code>java.util.HashMap</Code>, which is known to conform
- * exactly to the {@link Map} contract.  After the modification takes place
- * on both your map implementation and the confirmed map implementation, the
- * two maps are compared to see if their state is identical.  The comparison
- * also compares the collection views to make sure they're still the same.<P>
- *
- * The upshot of all that is that <I>any</I> test that modifies the map in
- * <I>any</I> way will verify that <I>all</I> of the map's state is still
- * correct, including the state of its collection views.  So for instance
- * if a key is removed by the map's key set's iterator, then the entry set
- * is checked to make sure the key/value pair no longer appears.<P>
- *
- * The {@link #map} field holds an instance of your collection implementation.
- * The {@link #entrySet}, {@link #keySet} and {@link #collectionValues} fields hold
- * that map's collection views.  And 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 maps, so that tests can proceed from a known state.<P>
- *
- * After a modification operation to both {@link #map} and {@link #confirmed},
- * the {@link #verify()} method is invoked to compare the results.  The {@link
- * verify()} method calls separate methods to verify the map and its three
- * collection views ({@link verifyMap(), {@link verifyEntrySet()}, {@link
- * verifyKeySet()}, and {@link verifyValues()}).  You may want to override one
- * of the verification methodsto perform additional verifications.  For
- * instance, {@link TestDoubleOrderedMap} would want override its {@link
- * #verifyValues()} method to verify that the values are unique and in
- * ascending order.<P>
- *
- * <B>Other Notes</B><P>
- *
- * If your {@link Map} fails one of these tests by design, you may still use
- * this base set of cases.  Simply override the test case (method) your {@link
- * Map} fails and/or the methods that define the assumptions used by the test
- * cases.  For example, if your map does not allow duplicate values, override
- * {@link #useDuplicateValues()} and have it return <code>false</code>
- *
- * @author Michael Smith
- * @author Rodney Waldhoff
- * @author Paul Jack
- * @version $Id: TestMap.java,v 1.20.2.1 2004/05/22 12:14:05 scolebourne Exp $
- */
-@SuppressWarnings({"unchecked", "rawtypes"})
-public abstract class TestMap extends TestObject{
-
-    // These instance variables are initialized with the reset method.
-    // Tests for map methods that alter the map (put, putAll, remove)
-    // first call reset() to create the map and its views; then perform
-    // the modification on the map; perform the same modification on the
-    // confirmed; and then call verify() to ensure that the map is equal
-    // to the confirmed, that the already-constructed collection views
-    // are still equal to the confirmed's collection views.
-
-
-    /** Map created by reset(). */
-    protected Map map;
-
-    /** Entry set of map created by reset(). */
-    protected Set entrySet;
-
-    /** Key set of map created by reset(). */
-    protected Set keySet;
-
-    /** Values collection of map created by reset(). */
-    protected Collection collectionValues;
-
-    /** HashMap created by reset(). */
-    protected Map confirmed;
-
-
-
-
-    /**
-     *  Override if your map does not allow a <code>null</code> key.  The
-     *  default implementation returns <code>true</code>
-     **/
-    protected boolean useNullKey() {
-        return true;
-    }
-
-    /**
-     *  Override if your map does not allow <code>null</code> values.  The
-     *  default implementation returns <code>true</code>.
-     **/
-    protected boolean useNullValue() {
-        return true;
-    }
-
-    /**
-     *  Override if your map does not allow duplicate values.  The default
-     *  implementation returns <code>true</code>.
-     **/
-    protected boolean useDuplicateValues() {
-        return true;
-    }
-
-    /**
-     *  Override if your map allows its mappings to be changed to new values.
-     *  The default implementation returns <code>true</code>.
-     **/
-    protected boolean isChangeable() {
-        return true;
-    }
-
-    /**
-     *  Override if your map does not allow add/remove modifications.  The
-     *  default implementation returns <code>true</code>.
-     **/
-    protected boolean isAddRemoveModifiable() {
-        return true;
-    }
-
-    /**
-     *  Override if your map allows concurrent modifications.  The default
-     *  implementation returns <code>true</code>.
-     **/
-    protected boolean isFailFastExpected() {
-        return true;
-    }
-
-    /**
-     *  Returns the set of keys in the mappings used to test the map.  This
-     *  method must return an array with the same length as {@link
-     *  #getSampleValues()} and all array elements must be different. The
-     *  default implementation constructs a set of String keys, and includes a
-     *  single null key if {@link #useNullKey()} returns <code>true</code>.
-     **/
-    protected Object[] getSampleKeys() {
-        Object[] result = new Object[] {
-            "blah", "foo", "bar", "baz", "tmp", "gosh", "golly", "gee",
-            "hello", "goodbye", "we'll", "see", "you", "all", "again",
-            "key",
-            "key2",
-            (useNullKey()) ? null : "nonnullkey"
-        };
-        return result;
-    }
-
-
-    protected Object[] getOtherKeys() {
-        return TestCollection.getOtherNonNullStringElements();
-    }
-
-    protected Object[] getOtherValues() {
-        return TestCollection.getOtherNonNullStringElements();
-    }
-
-    /**
-     *  Returns the set of values in the mappings used to test the map.  This
-     *  method must return an array with the same length as {@link
-     *  #getSampleKeys()}.  The default implementation contructs a set of
-     *  String values and includes a single null value if {@link
-     *  #useNullValue()} returns <code>true</code>, and includes two values
-     *  that are the same if {@link #useDuplicateValues()} returns
-     *  <code>true</code>.
-     **/
-    protected Object[] getSampleValues() {
-        Object[] result = new Object[] {
-            "blahv", "foov", "barv", "bazv", "tmpv", "goshv", "gollyv", "geev",
-            "hellov", "goodbyev", "we'llv", "seev", "youv", "allv", "againv",
-            (useNullValue()) ? null : "nonnullvalue",
-            "value",
-            (useDuplicateValues()) ? "value" : "value2",
-        };
-        return result;
-    }
-
-    /**
-     *  Returns a the set of values that can be used to replace the values
-     *  returned from {@link #getSampleValues()}.  This method must return an
-     *  array with the same length as {@link #getSampleValues()}.  The values
-     *  returned from this method should not be the same as those returned from
-     *  {@link #getSampleValues()}.  The default implementation constructs a
-     *  set of String values and includes a single null value if {@link
-     *  #useNullValue()} returns <code>true</code>, and includes two values
-     *  that are the same if {@link #useDuplicateValues()} returns
-     *  <code>true</code>.
-     **/
-    protected Object[] getNewSampleValues() {
-        Object[] result = new Object[] {
-            (useNullValue()) ? null : "newnonnullvalue",
-            "newvalue",
-            (useDuplicateValues()) ? "newvalue" : "newvalue2",
-            "newblahv", "newfoov", "newbarv", "newbazv", "newtmpv", "newgoshv",
-            "newgollyv", "newgeev", "newhellov", "newgoodbyev", "newwe'llv",
-            "newseev", "newyouv", "newallv", "newagainv",
-        };
-        return result;
-    }
-
-    /**
-     *  Helper method to add all the mappings described by {@link
-     *  #getSampleKeys()} and {@link #getSampleValues()}.
-     **/
-    protected void addSampleMappings(Map m) {
-
-        Object[] keys = getSampleKeys();
-        Object[] values = getSampleValues();
-
-        for(int i = 0; i < keys.length; i++) {
-            try {
-                m.put(keys[i], values[i]);
-            } catch (NullPointerException exception) {
-                assertTrue("NullPointerException only allowed to be thrown " +
-                           "if either the key or value is null.",
-                           keys[i] == null || values[i] == null);
-
-                if (keys[i] == null) {
-                  if (useNullKey()) {
-                    throw new Error("NullPointerException on null key, but " +
-                        "useNullKey is not overridden to return false.", exception);
-                  }
-                } else if (values[i] == null) {
-                  if (useNullValue()) {
-                    throw new Error("NullPointerException on null value, but " +
-                        "useNullValue is not overridden to return false.", exception);
-                  }
-                } else {
-                  // Unknown reason for NullPointer.
-                  throw exception;
-                }
-            }
-        }
-        assertEquals("size must reflect number of mappings added.",
-                     keys.length, m.size());
-    }
-
-    /**
-     * Return a new, empty {@link Map} to be used for testing.
-     */
-    protected abstract Map makeEmptyMap();
-
-    protected Map makeConfirmedMap() {
-      return new HashMap();
-    }
-
-    /**
-     *  Return a new, populated map.  The mappings in the map should match the
-     *  keys and values returned from {@link #getSampleKeys()} and {@link
-     *  #getSampleValues()}.  The default implementation uses makeEmptyMap()
-     *  and calls {@link #addSampleMappings()} to add all the mappings to the
-     *  map.
-     **/
-    protected Map makeFullMap() {
-        Map m = makeEmptyMap();
-        addSampleMappings(m);
-        return m;
-    }
-
-    @Override
-    public Object makeObject() {
-        return makeEmptyMap();
-    }
-
-    public void testSpecialKeysValues() {
-      String[] keys = {"toString", "constructor", "__proto__", "", "null"};
-      Object[] values = {new Object(), new Object(), new Object(), new Object(), null};
-
-      Map map = makeEmptyMap();
-
-      assertMap(map, keys, values);
-
-      Object[] undefineds = new Object[values.length];
-      Arrays.fill(undefineds, getUndefined());
-      assertMap(map, keys, undefineds);
-    }
-
-    private void assertMap(Map map, String[] keys, Object[] values) {
-      assertEmptyMap(map, keys, values);
-
-      // Fill the map with special keys/values.
-      for (int i = 0; i < keys.length; i++) {
-        map.put(keys[i], values[i]);
-      }
-
-      // Assert the map with filled in keys/values
-      for (int i = 0; i < keys.length; i++) {
-        assertTrue(keys[i], map.containsKey(keys[i]));
-        assertTrue(keys[i], map.containsValue(values[i]));
-        assertSame(keys[i], values[i], map.get(keys[i]));
-      }
-      assertEquals(map.toString(), keys.length, map.size());
-
-      // Remove the keys and assert the results
-      for (int i = 0; i < keys.length; i++) {
-        assertSame(keys[i], values[i], map.remove(keys[i]));
-      }
-      assertEmptyMap(map, keys, values);
-    }
-
-    private static void assertEmptyMap(Map map, final String[] keys, final Object[] values) {
-      for (int i = 0; i < keys.length; i++) {
-        assertFalse(keys[i], map.containsKey(keys[i]));
-        assertFalse(keys[i], map.containsValue(values[i]));
-        assertNull(keys[i], map.get(keys[i]));
-      }
-    }
-
-    private static Object getUndefined() {
-      if (TestUtils.isJvm()) {
-        return null;
-      }
-      return getUndefinedImpl();
-    }
-
-    @JsProperty(name = "undefined", namespace = JsPackage.GLOBAL)
-    private native static Object getUndefinedImpl();
-
-    /**
-     *  Test to ensure the test setup is working properly.  This method checks
-     *  to ensure that the getSampleKeys and getSampleValues methods are
-     *  returning results that look appropriate.  That is, they both return a
-     *  non-null array of equal length.  The keys array must not have any
-     *  duplicate values, and may only contain a (single) null key if
-     *  useNullKey() returns true.  The values array must only have a null
-     *  value if useNullValue() is true and may only have duplicate values if
-     *  useDuplicateValues() returns true.
-     **/
-    public void testSampleMappings() {
-      Object[] keys = getSampleKeys();
-      Object[] values = getSampleValues();
-      Object[] newValues = getNewSampleValues();
-
-      assertTrue("failure in test: Must have keys returned from " +
-                 "getSampleKeys.", keys != null);
-
-      assertTrue("failure in test: Must have values returned from " +
-                 "getSampleValues.", values != null);
-
-      // verify keys and values have equivalent lengths (in case getSampleX are
-      // overridden)
-      assertEquals("failure in test: not the same number of sample " +
-                   "keys and values.",  keys.length, values.length);
-
-      assertEquals("failure in test: not the same number of values and new values.",
-                   values.length, newValues.length);
-
-      // verify there aren't duplicate keys, and check values
-      for(int i = 0; i < keys.length - 1; i++) {
-          for(int j = i + 1; j < keys.length; j++) {
-              assertTrue("failure in test: duplicate null keys.",
-                         (keys[i] != null || keys[j] != null));
-              assertTrue("failure in test: duplicate non-null key.",
-                         (keys[i] == null || keys[j] == null ||
-                          (!keys[i].equals(keys[j]) &&
-                           !keys[j].equals(keys[i]))));
-          }
-          assertTrue("failure in test: found null key, but useNullKey " +
-                     "is false.", keys[i] != null || useNullKey());
-          assertTrue("failure in test: found null value, but useNullValue " +
-                     "is false.", values[i] != null || useNullValue());
-          assertTrue("failure in test: found null new value, but useNullValue " +
-                     "is false.", newValues[i] != null || useNullValue());
-          assertTrue("failure in test: values should not be the same as new value",
-                     values[i] != newValues[i] &&
-                     (values[i] == null || !values[i].equals(newValues[i])));
-      }
-    }
-
-    // tests begin here.  Each test adds a little bit of tested functionality.
-    // Many methods assume previous methods passed.  That is, they do not
-    // exhaustively recheck things that have already been checked in a previous
-    // test methods.
-
-    /**
-     *  Test to ensure that makeEmptyMap and makeFull returns a new non-null
-     *  map with each invocation.
-     **/
-    public void testMakeMap() {
-        Map em = makeEmptyMap();
-        assertTrue("failure in test: makeEmptyMap must return a non-null map.",
-                   em != null);
-
-        Map em2 = makeEmptyMap();
-        assertTrue("failure in test: makeEmptyMap must return a non-null map.",
-                   em != null);
-
-        assertTrue("failure in test: makeEmptyMap must return a new map " +
-                   "with each invocation.", em != em2);
-
-        Map fm = makeFullMap();
-        assertTrue("failure in test: makeFullMap must return a non-null map.",
-                   fm != null);
-
-        Map fm2 = makeFullMap();
-        assertTrue("failure in test: makeFullMap must return a non-null map.",
-                   fm != null);
-
-        assertTrue("failure in test: makeFullMap must return a new map " +
-                   "with each invocation.", fm != fm2);
-    }
-
-    /**
-     *  Tests Map.isEmpty()
-     **/
-    public void testMapIsEmpty() {
-
-        resetEmpty();
-        assertEquals("Map.isEmpty() should return true with an empty map",
-                     true, map.isEmpty());
-         verify();
-
-        resetFull();
-        assertEquals("Map.isEmpty() should return false with a non-empty map",
-                     false, map.isEmpty());
-         verify();
-          }
-
-    /**
-     *  Tests Map.size()
-     **/
-    public void testMapSize() {
-        resetEmpty();
-        assertEquals("Map.size() should be 0 with an empty map",
-                     0, map.size());
-        verify();
-
-        resetFull();
-        assertEquals("Map.size() should equal the number of entries " +
-                     "in the map", getSampleKeys().length, map.size());
-        verify();
-    }
-
-    /**
-     *  Tests {@link Map#clear()}.  If the map {@link #isAddRemoveModifiable()
-     *  can add and remove elements}, then {@link Map#size()} and {@link
-     *  Map#isEmpty()} are used to ensure that map has no elements after a call
-     *  to clear.  If the map does not support adding and removing elements,
-     *  this method checks to ensure clear throws an
-     *  UnsupportedOperationException.
-     **/
-    public void testMapClear() {
-        if (!isAddRemoveModifiable()) return;
-
-        resetEmpty();
-        map.clear();
-        confirmed.clear();
-        verify();
-
-        resetFull();
-        map.clear();
-        confirmed.clear();
-        verify();
-    }
-
-
-    /**
-     *  Tests Map.containsKey(Object) by verifying it returns false for all
-     *  sample keys on a map created using an empty map and returns true for
-     *  all sample keys returned on a full map.
-     **/
-    public void testMapContainsKey() {
-        Object[] keys = getSampleKeys();
-
-        resetEmpty();
-        for(int i = 0; i < keys.length; i++) {
-            assertTrue("Map must not contain key when map is empty",
-                       !map.containsKey(keys[i]));
-        }
-        verify();
-
-        resetFull();
-        for(int i = 0; i < keys.length; i++) {
-            assertTrue("Map must contain key for a mapping in the map. " +
-		       "Missing: " + keys[i], map.containsKey(keys[i]));
-        }
-        verify();
-    }
-
-    /**
-     *  Tests Map.containsValue(Object) by verifying it returns false for all
-     *  sample values on an empty map and returns true for all sample values on
-     *  a full map.
-     **/
-    public void testMapContainsValue() {
-        Object[] values = getSampleValues();
-
-        resetEmpty();
-        for(int i = 0; i < values.length; i++) {
-            assertTrue("Empty map must not contain value",
-                       !map.containsValue(values[i]));
-        }
-        verify();
-
-        resetFull();
-        for(int i = 0; i < values.length; i++) {
-            assertTrue("Map must contain value for a mapping in the map.",
-                       map.containsValue(values[i]));
-        }
-        verify();
-    }
-
-
-    /**
-     *  Tests Map.equals(Object)
-     **/
-    public void testMapEquals() {
-        resetEmpty();
-        assertTrue("Empty maps unequal.", map.equals(confirmed));
-        verify();
-
-        resetFull();
-        assertTrue("Full maps unequal.", map.equals(confirmed));
-        verify();
-
-        resetFull();
-	// modify the HashMap created from the full map and make sure this
-	// change results in map.equals() to return false.
-        Iterator iter = confirmed.keySet().iterator();
-        iter.next();
-        iter.remove();
-        assertTrue("Different maps equal.", !map.equals(confirmed));
-
-        resetFull();
-        assertTrue("equals(null) returned true.", !map.equals(null));
-        assertTrue("equals(new Object()) returned true.",
-		   !map.equals(new Object()));
-        verify();
-    }
-
-
-    /**
-     *  Tests Map.get(Object)
-     **/
-    public void testMapGet() {
-      resetEmpty();
-
-      Object[] keys = getSampleKeys();
-      Object[] values = getSampleValues();
-
-      for (int i = 0; i < keys.length; i++) {
-        assertTrue("Empty map.get() should return null.",
-            map.get(keys[i]) == null);
-      }
-      verify();
-
-      resetFull();
-      for (int i = 0; i < keys.length; i++) {
-        assertEquals("Full map.get() should return value from mapping.",
-            values[i], map.get(keys[i]));
-      }
-    }
-
-    /**
-     *  Tests Map.hashCode()
-     **/
-    public void testMapHashCode() {
-      resetEmpty();
-      assertTrue("Empty maps have different hashCodes.",
-          map.hashCode() == confirmed.hashCode());
-
-      resetFull();
-      assertTrue("Equal maps have different hashCodes.",
-          map.hashCode() == confirmed.hashCode());
-    }
-
-    /**
-     *  Tests Map.toString().  Since the format of the string returned by the
-     *  toString() method is not defined in the Map interface, there is no
-     *  common way to test the results of the toString() method.  Thereforce,
-     *  it is encouraged that Map implementations override this test with one
-     *  that checks the format matches any format defined in its API.  This
-     *  default implementation just verifies that the toString() method does
-     *  not return null.
-     **/
-    public void testMapToString() {
-      resetEmpty();
-      assertTrue("Empty map toString() should not return null",
-          map.toString() != null);
-      verify();
-
-      resetFull();
-      assertTrue("Empty map toString() should not return null",
-          map.toString() != null);
-      verify();
-    }
-
-
-
-
-
-    /**
-     *  Tests Map.put(Object, Object)
-     **/
-    public void testMapPut() {
-      if (!isAddRemoveModifiable()) return;
-
-      resetEmpty();
-
-      Object[] keys = getSampleKeys();
-      Object[] values = getSampleValues();
-      Object[] newValues = getNewSampleValues();
-
-      for(int i = 0; i < keys.length; i++) {
-        Object o = map.put(keys[i], values[i]);
-        confirmed.put(keys[i], values[i]);
-        verify();
-        assertTrue("First map.put should return null", o == null);
-        assertTrue("Map should contain key after put",
-            map.containsKey(keys[i]));
-        assertTrue("Map should contain value after put",
-            map.containsValue(values[i]));
-      }
-
-      for(int i = 0; i < keys.length; i++) {
-        Object o = map.put(keys[i], newValues[i]);
-        confirmed.put(keys[i], newValues[i]);
-        verify();
-        assertEquals("Second map.put should return previous value",
-            values[i], o);
-        assertTrue("Map should still contain key after put",
-            map.containsKey(keys[i]));
-        assertTrue("Map should contain new value after put",
-            map.containsValue(newValues[i]));
-
-        // if duplicates are allowed, we're not guarunteed that the value
-        // no longer exists, so don't try checking that.
-        if(!useDuplicateValues()) {
-          assertTrue("Map should not contain old value after second put",
-              !map.containsValue(values[i]));
-        }
-      }
-    }
-
-    /**
-     *  Tests Map.putAll(Collection)
-     **/
-    public void testMapPutAll() {
-      if (!isAddRemoveModifiable()) return;
-
-      resetEmpty();
-
-      Map m2 = makeFullMap();
-
-      map.putAll(m2);
-      confirmed.putAll(m2);
-      verify();
-
-      resetEmpty();
-
-      m2 = new HashMap();
-      Object[] keys = getSampleKeys();
-      Object[] values = getSampleValues();
-      for(int i = 0; i < keys.length; i++) {
-        m2.put(keys[i], values[i]);
-      }
-
-      map.putAll(m2);
-      confirmed.putAll(m2);
-      verify();
-    }
-
-    /**
-     *  Tests Map.remove(Object)
-     **/
-    public void testMapRemove() {
-      if (!isAddRemoveModifiable()) return;
-
-      resetEmpty();
-
-      Object[] keys = getSampleKeys();
-      Object[] values = getSampleValues();
-      for(int i = 0; i < keys.length; i++) {
-        Object o = map.remove(keys[i]);
-        assertTrue("First map.remove should return null", o == null);
-      }
-      verify();
-
-      resetFull();
-
-      for(int i = 0; i < keys.length; i++) {
-        Object o = map.remove(keys[i]);
-        confirmed.remove(keys[i]);
-        verify();
-
-        assertEquals("map.remove with valid key should return value",
-            values[i], o);
-      }
-
-      Object[] other = getOtherKeys();
-
-      resetFull();
-      int size = map.size();
-      for (int i = 0; i < other.length; i++) {
-        Object o = map.remove(other[i]);
-        assertEquals("map.remove for nonexistent key should return null",
-            o, null);
-        assertEquals("map.remove for nonexistent key should not " +
-            "shrink map", size, map.size());
-      }
-      verify();
-    }
-
-    public void testFailFastEntrySet() {
-        if (!isAddRemoveModifiable()) {
-            return;
-        }
-        if (!isFailFastExpected()) {
-            return;
-        }
-        resetFull();
-        Iterator<Map.Entry> it = map.entrySet().iterator();
-        final Map.Entry val = it.next();
-        map.remove(val.getKey());
-        try {
-            it.next();
-            fail();
-        } catch (ConcurrentModificationException expected) {}
-
-        resetFull();
-        it = map.entrySet().iterator();
-        it.next();
-        map.clear();
-        try {
-            it.next();
-            fail();
-        } catch (ConcurrentModificationException expected) {}
-    }
-
-    public void testFailFastKeySet() {
-        if (!isAddRemoveModifiable()) {
-            return;
-        }
-        if (!isFailFastExpected()) {
-            return;
-        }
-        resetFull();
-        Iterator it = map.keySet().iterator();
-        final Object val = it.next();
-        map.remove(val);
-        try {
-            it.next();
-            fail();
-        } catch (ConcurrentModificationException expected) {}
-
-        resetFull();
-        it = map.keySet().iterator();
-        it.next();
-        map.clear();
-        try {
-            it.next();
-            fail();
-        } catch (ConcurrentModificationException expected) {}
-    }
-
-    public void testFailFastValues() {
-        if (!isAddRemoveModifiable()) {
-            return;
-        }
-        if (!isFailFastExpected()) {
-            return;
-        }
-        resetFull();
-        Iterator it = map.values().iterator();
-        it.next();
-        map.remove(map.keySet().iterator().next());
-        try {
-            it.next();
-            fail();
-        } catch (ConcurrentModificationException expected) {}
-
-        resetFull();
-        it = map.values().iterator();
-        it.next();
-        map.clear();
-        try {
-            it.next();
-            fail();
-        } catch (ConcurrentModificationException expected) {}
-    }
-
-    /**
-     *  Utility methods to create an array of Map.Entry objects
-     *  out of the given key and value arrays.<P>
-     *
-     *  @param keys    the array of keys
-     *  @param values  the array of values
-     *  @return an array of Map.Entry of those keys to those values
-     */
-    private Map.Entry[] makeEntryArray(Object[] keys, Object[] values) {
-        Map.Entry[] result = new Map.Entry[keys.length];
-        for (int i = 0; i < keys.length; i++) {
-            result[i] = new DefaultMapEntry(keys[i], values[i]);
-        }
-        return result;
-    }
-
-
-    class TestMapEntrySet extends TestSet {
-        public TestMapEntrySet() {
-            super("");
-        }
-
-        // Have to implement manually; entrySet doesn't support addAll
-        @Override
-        protected Object[] getFullElements() {
-            Object[] k = getSampleKeys();
-            Object[] v = getSampleValues();
-            return makeEntryArray(k, v);
-        }
-
-        // Have to implement manually; entrySet doesn't support addAll
-        @Override
-        protected Object[] getOtherElements() {
-            Object[] k = getOtherKeys();
-            Object[] v = getOtherValues();
-            return makeEntryArray(k, v);
-        }
-
-        @Override
-        protected Set makeEmptySet() {
-            return makeEmptyMap().entrySet();
-        }
-
-        @Override
-        protected Set makeFullSet() {
-            return makeFullMap().entrySet();
-        }
-
-        @Override
-        protected boolean isAddSupported() {
-            // Collection views don't support add operations.
-            return false;
-        }
-
-        @Override
-        protected boolean isRemoveSupported() {
-            // Entry set should only support remove if map does
-            return isAddRemoveModifiable();
-        }
-
-        @Override
-        protected void resetFull() {
-            TestMap.this.resetFull();
-            collection = map.entrySet();
-            TestMapEntrySet.this.confirmed = TestMap.this.confirmed.entrySet();
-        }
-
-        @Override
-        protected void resetEmpty() {
-            TestMap.this.resetEmpty();
-            collection = map.entrySet();
-            TestMapEntrySet.this.confirmed = TestMap.this.confirmed.entrySet();
-        }
-
-        @Override
-        protected void verify() {
-            super.verify();
-            TestMap.this.verify();
-        }
-    }
-
-
-
-    class TestMapKeySet extends TestSet {
-        public TestMapKeySet() {
-            super("");
-        }
-        @Override
-        protected Object[] getFullElements() {
-            return getSampleKeys();
-        }
-
-        @Override
-        protected Object[] getOtherElements() {
-            return getOtherKeys();
-        }
-
-        @Override
-        protected Set makeEmptySet() {
-            return makeEmptyMap().keySet();
-        }
-
-        @Override
-        protected Set makeFullSet() {
-            return makeFullMap().keySet();
-        }
-
-        @Override
-        protected boolean isAddSupported() {
-            return false;
-        }
-
-        @Override
-        protected boolean isRemoveSupported() {
-            return isAddRemoveModifiable();
-        }
-
-        @Override
-        protected void resetEmpty() {
-            TestMap.this.resetEmpty();
-            collection = map.keySet();
-            TestMapKeySet.this.confirmed = TestMap.this.confirmed.keySet();
-        }
-
-        @Override
-        protected void resetFull() {
-            TestMap.this.resetFull();
-            collection = map.keySet();
-            TestMapKeySet.this.confirmed = TestMap.this.confirmed.keySet();
-        }
-
-        @Override
-        protected void verify() {
-            super.verify();
-            TestMap.this.verify();
-        }
-    }
-
-
-
-    class TestMapValues extends TestCollection {
-        public TestMapValues() {
-
-        }
-
-        @Override
-        protected Object[] getFullElements() {
-            return getSampleValues();
-        }
-
-        @Override
-        protected Object[] getOtherElements() {
-            return getOtherValues();
-        }
-
-        @Override
-        protected Collection makeCollection() {
-            return makeEmptyMap().values();
-        }
-
-        @Override
-        protected Collection makeFullCollection() {
-            return makeFullMap().values();
-        }
-
-        @Override
-        protected boolean isAddSupported() {
-            return false;
-        }
-
-        @Override
-        protected boolean isRemoveSupported() {
-            return isAddRemoveModifiable();
-        }
-
-        @Override
-        protected boolean areEqualElementsDistinguishable() {
-            // equal values are associated with different keys, so they are
-            // distinguishable.
-            return true;
-        }
-
-        @Override
-        protected Collection makeConfirmedCollection() {
-            // never gets called, reset methods are overridden
-            return null;
-        }
-
-        @Override
-        protected Collection makeConfirmedFullCollection() {
-            // never gets called, reset methods are overridden
-            return null;
-        }
-
-        @Override
-        protected void resetFull() {
-            TestMap.this.resetFull();
-            collection = map.values();
-            TestMapValues.this.confirmed = TestMap.this.confirmed.values();
-        }
-
-        @Override
-        protected void resetEmpty() {
-            TestMap.this.resetEmpty();
-            collection = map.values();
-            TestMapValues.this.confirmed = TestMap.this.confirmed.values();
-        }
-
-        @Override
-        protected void verify() {
-            super.verify();
-            TestMap.this.verify();
-        }
-
-        // TODO: should test that a remove on the values collection view
-        // removes the proper mapping and not just any mapping that may have
-        // the value equal to the value returned from the values iterator.
-    }
-
-
-    /**
-     *  Resets the {@link #map}, {@link #entrySet}, {@link #keySet},
-     *  {@link #collectionValues} and {@link #confirmed} fields to empty.
-     */
-    protected void resetEmpty() {
-        this.map = makeEmptyMap();
-        views();
-        this.confirmed = makeConfirmedMap();
-    }
-
-
-    /**
-     *  Resets the {@link #map}, {@link #entrySet}, {@link #keySet},
-     *  {@link #collectionValues} and {@link #confirmed} fields to full.
-     */
-    protected void resetFull() {
-        this.map = makeFullMap();
-        views();
-        this.confirmed = makeConfirmedMap();
-        Object[] k = getSampleKeys();
-        Object[] v = getSampleValues();
-        for (int i = 0; i < k.length; i++) {
-            confirmed.put(k[i], v[i]);
-        }
-    }
-
-
-    /**
-     *  Resets the collection view fields.
-     */
-    private void views() {
-        this.keySet = map.keySet();
-        this.collectionValues = map.values();
-        this.entrySet = map.entrySet();
-    }
-
-
-    /**
-     *  Verifies that {@link #map} is still equal to {@link #confirmed}.
-     *  This method checks that the map is equal to the HashMap,
-     *  <I>and</I> that the map's collection views are still equal to
-     *  the HashMap's collection views.  An <Code>equals</Code> test
-     *  is done on the maps and their collection views; their size and
-     *  <Code>isEmpty</Code> results are compared; their hashCodes are
-     *  compared; and <Code>containsAll</Code> tests are run on the
-     *  collection views.
-     */
-    protected void verify() {
-        verifyMap();
-        verifyEntrySet();
-        verifyKeySet();
-
-    }
-
-    protected void verifyMap() {
-        int size = confirmed.size();
-        boolean empty = confirmed.isEmpty();
-        assertEquals("Map should be same size as HashMap",
-                     size, map.size());
-        assertEquals("Map should be empty if HashMap is",
-                     empty, map.isEmpty());
-        assertEquals("hashCodes should be the same",
-                     confirmed.hashCode(), map.hashCode());
-        // this fails for LRUMap because confirmed.equals() somehow modifies
-        // map, causing concurrent modification exceptions.
-        //assertEquals("Map should still equal HashMap", confirmed, map);
-        // this works though and performs the same verification:
-        assertTrue("Map should still equal HashMap", map.equals(confirmed));
-        // TODO: this should really be rexamined to figure out why LRU map
-        // behaves like it does (the equals shouldn't modify since all accesses
-        // by the confirmed collection should be through an iterator, thus not
-        // causing LRUMap to change).
-    }
-
-    protected void verifyEntrySet() {
-        int size = confirmed.size();
-        boolean empty = confirmed.isEmpty();
-        assertEquals("entrySet should be same size as HashMap's",
-                     size, entrySet.size());
-        assertEquals("entrySet should be empty if HashMap is",
-                     empty, entrySet.isEmpty());
-        assertTrue("entrySet should contain all HashMap's elements",
-                   entrySet.containsAll(confirmed.entrySet()));
-        assertEquals("entrySet hashCodes should be the same",
-                     confirmed.entrySet().hashCode(), entrySet.hashCode());
-        assertEquals("Map's entry set should still equal HashMap's",
-                     confirmed.entrySet(), entrySet);
-    }
-
-    protected void verifyKeySet() {
-        int size = confirmed.size();
-        boolean empty = confirmed.isEmpty();
-        assertEquals("keySet should be same size as HashMap's",
-                     size, keySet.size());
-        assertEquals("keySet should be empty if HashMap is",
-                     empty, keySet.isEmpty());
-        assertTrue("keySet should contain all HashMap's elements",
-                   keySet.containsAll(confirmed.keySet()));
-        assertEquals("keySet hashCodes should be the same",
-                     confirmed.keySet().hashCode(), keySet.hashCode());
-        assertEquals("Map's key set should still equal HashMap's",
-                     confirmed.keySet(), keySet);
-    }
-
-}
diff --git a/user/test/org/apache/commons/collections/TestObject.java b/user/test/org/apache/commons/collections/TestObject.java
deleted file mode 100644
index a66cce2..0000000
--- a/user/test/org/apache/commons/collections/TestObject.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-  
-import com.google.gwt.emultest.java.util.EmulTestBase;
-
-/**
- * Tests base {@link java.lang.Object} methods and contracts.
- * <p>
- * To use, simply extend this class, and implement
- * the {@link #makeObject()} method.
- * <p>
- * If your {@link Object} fails one of these tests by design,
- * you may still use this base set of cases.  Simply override the
- * test case (method) your {@link Object} fails.
- *
- * @author Rodney Waldhoff
- * @version $Id: TestObject.java,v 1.13.2.1 2004/05/22 12:14:05 scolebourne Exp $
- */
-public abstract class TestObject extends EmulTestBase {
-   
-
-    // current major release for Collections
-    public static final int COLLECTIONS_MAJOR_VERSION = 2;
-
-    /**
-     * This constant makes it possible for TestMap (and other subclasses,
-     * if necessary) to automatically check CVS for a versionX copy of a
-     * Serialized object, so we can make sure that compatibility is maintained.
-     * See, for example, TestMap.getCanonicalFullMapName(Map map).
-     * Subclasses can override this variable, indicating compatibility
-     * with earlier Collections versions.
-     * Defaults to 1, the earliest Collections version.  (Note: some
-     * collections did not even exist in this version).
-     * 
-     * @return 1
-     */
-    public int getCompatibilityVersion() {
-        return 1;
-    }
-
-    /**
-     * Return a new, empty {@link Object} to used for testing.
-     */
-    public abstract Object makeObject();
-
-    public void testObjectEqualsSelf() {
-        Object obj = makeObject();
-        assertEquals("A Object should equal itself",obj,obj);
-    }
-
-    public void testObjectHashCodeEqualsSelfHashCode() {
-        Object obj = makeObject();
-        assertEquals("hashCode should be repeatable",obj.hashCode(),obj.hashCode());
-    }
-
-    public void testObjectHashCodeEqualsContract() {
-        Object obj1 = makeObject();
-        if(obj1.equals(obj1)) {
-            assertEquals("[1] When two objects are equal, their hashCodes should be also.",obj1.hashCode(),obj1.hashCode());
-        }
-        Object obj2 = makeObject();
-        if(obj1.equals(obj2)) {
-            assertEquals("[2] When two objects are equal, their hashCodes should be also.",obj1.hashCode(),obj2.hashCode());
-            assertTrue("When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true", obj2.equals(obj1));
-        }
-    }
-
-    
-
-    public String getCanonicalEmptyCollectionName(Object object) {
-        StringBuffer retval = new StringBuffer();
-        retval.append("data/test/");
-        String colName = object.getClass().getName();
-        
-        colName = colName.substring(colName.lastIndexOf(".")+1,colName.length());
-        retval.append(colName);
-        retval.append(".emptyCollection.version");
-        retval.append(getCompatibilityVersion());
-        retval.append(".obj");
-        return retval.toString();
-    }
-
-    public String getCanonicalFullCollectionName(Object object) {
-        StringBuffer retval = new StringBuffer();
-        retval.append("data/test/");
-        String colName = object.getClass().getName();
-        colName = colName.substring(colName.lastIndexOf(".")+1,colName.length());
-        retval.append(colName);
-        retval.append(".fullCollection.version");
-        retval.append(getCompatibilityVersion());
-        retval.append(".obj");
-        return retval.toString();
-    }
-
-    /**
-     * Override this method if a subclass is testing a 
-     * Collections that cannot serialize an "empty" Collection
-     * (e.g. Comparators have no contents)
-     * 
-     * @return true
-     */
-    public boolean supportsEmptyCollections() {
-        return true;
-    }
-
-    /**
-     * Override this method if a subclass is testing a 
-     * Collections that cannot serialize a "full" Collection
-     * (e.g. Comparators have no contents)
-     * 
-     * @return true
-     */
-    public boolean supportsFullCollections() {
-        return true;
-    }
-
-
-  
-}
diff --git a/user/test/org/apache/commons/collections/TestSet.java b/user/test/org/apache/commons/collections/TestSet.java
deleted file mode 100644
index 69580f0..0000000
--- a/user/test/org/apache/commons/collections/TestSet.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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.
- */
-package org.apache.commons.collections;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- *  Tests base {@link Set} methods and contracts.<P>
- *
- *  Since {@link Set} doesn't stipulate much new behavior that isn't already
- *  found in {@link Collection}, this class basically just adds tests for
- *  {@link Set#equals()} and {@link Set#hashCode()} along with an updated
- *  {@link #verify()} that ensures elements do not appear more than once in the
- *  set.<P>
- *
- *  To use, subclass and override the {@link #makeEmptySet()}
- *  method.  You may have to override other protected methods if your
- *  set is not modifiable, or if your set restricts what kinds of
- *  elements may be added; see {@link TestCollection} for more details.<P>
- *
- *  @author Paul Jack
- *  @version $Id: TestSet.java,v 1.2.2.1 2004/05/22 12:14:05 scolebourne Exp $
- */
-@SuppressWarnings({"unchecked", "rawtypes"})
-public abstract class TestSet extends TestCollection {
-
-
-    /**
-     *  Constructor.
-     *
-     *  @param name  name for test
-     */
-    public TestSet(String name) {
-      
-    }
-
-
-    /**
-     *  Makes an empty collection by invoking {@link #makeEmptySet()}.  
-     *
-     *  @return an empty collection
-     */
-    @Override
-    protected final Collection makeCollection() {
-        return makeEmptySet();
-    }
-
-
-    /**
-     *  Makes a full collection by invoking {@link #makeFullSet()}.
-     *
-     *  @return a full collection
-     */
-    @Override
-    protected final Collection makeFullCollection() {
-        return makeFullSet();
-    }
-
-    /**
-     *  Return the {@link TestCollection#collection} fixture, but cast as a
-     *  Set.  
-     */
-    protected Set getSet() {
-        return (Set)collection;
-    }
-
-    /**
-     *  Returns an empty {@link HashSet} for use in modification testing.
-     *
-     *  @return a confirmed empty collection
-     */
-    @Override
-    protected Collection makeConfirmedCollection() {
-        return new HashSet();
-    }
-
-
-    /**
-     *  Returns a full {@link HashSet} for use in modification testing.
-     *
-     *  @return a confirmed full collection
-     */
-    @Override
-    protected Collection makeConfirmedFullCollection() {
-        HashSet set = new HashSet();
-        set.addAll(Arrays.asList(getFullElements()));
-        return set;
-    }
-
-    /**
-     *  Return the {@link TestCollection#confirmed} fixture, but cast as a 
-     *  Set.
-     **/
-    protected Set getConfirmedSet() {
-        return (Set)confirmed;
-    }
-
-    /**
-     *  Makes an empty set.  The returned set should have no elements.
-     *
-     *  @return an empty set
-     */
-    protected abstract Set makeEmptySet();
-
-
-    /**
-     *  Makes a full set by first creating an empty set and then adding
-     *  all the elements returned by {@link #getFullElements()}.
-     *
-     *  Override if your set does not support the add operation.
-     *
-     *  @return a full set
-     */
-    protected Set makeFullSet() {
-        Set set = makeEmptySet();
-        set.addAll(Arrays.asList(getFullElements()));
-        return set;
-    }
-
-
-    /**
-     *  Tests {@link Set#equals(Object)}.
-     */
-    public void testSetEquals() {
-        resetEmpty();
-        assertEquals("Empty sets should be equal", 
-                     getSet(), getConfirmedSet());
-        verify();
-
-        HashSet set2 = new HashSet();
-        set2.add("foo");
-        assertTrue("Empty set shouldn't equal nonempty set", 
-                   !getSet().equals(set2));
-
-        resetFull();
-        assertEquals("Full sets should be equal", getSet(), getConfirmedSet());
-        verify();
-
-        set2.clear();
-        set2.addAll(Arrays.asList(getOtherElements()));
-        assertTrue("Sets with different contents shouldn't be equal", 
-                   !getSet().equals(set2));
-    }
-
-
-    /**
-     *  Tests {@link Set#hashCode()}.
-     */
-    public void testSetHashCode() {
-        resetEmpty();
-        assertEquals("Empty sets have equal hashCodes", 
-                     getSet().hashCode(), getConfirmedSet().hashCode());
-
-        resetFull();
-        assertEquals("Equal sets have equal hashCodes", 
-                     getSet().hashCode(), getConfirmedSet().hashCode());
-    }
-
-
-    /**
-     *  Provides additional verifications for sets.
-     */
-    @Override
-    protected void verify() {
-        super.verify();
-        assertEquals("Sets should be equal", confirmed, collection);
-        assertEquals("Sets should have equal hashCodes", 
-                     confirmed.hashCode(), collection.hashCode());
-        HashSet set = new HashSet();
-        Iterator iterator = collection.iterator();
-        while (iterator.hasNext()) {
-            assertTrue("Set.iterator should only return unique elements", 
-                       set.add(iterator.next()));
-        }
-    }
-
-}
diff --git a/user/test/org/apache/commons/collections/package-info.java b/user/test/org/apache/commons/collections/package-info.java
deleted file mode 100644
index a1615b4..0000000
--- a/user/test/org/apache/commons/collections/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * 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.
- */
-
-/**
- * This packages code originated from Apache, so it seperate from gwt
- * code. However, as gwt does not support all of Apache Collections,
- * this package has been <b>heavily</b> modified, so replace it with a
- * new version only if you wish to do all the modifications again.
- */
-package org.apache.commons.collections;
