You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/06/01 00:17:39 UTC

svn commit: r780520 - in /incubator/pivot/trunk: core/src/pivot/collections/ core/src/pivot/collections/adapter/ core/src/pivot/serialization/ core/src/pivot/util/ core/test/pivot/core/test/ demos/src/pivot/demos/million/ tutorials/src/pivot/tutorials/...

Author: gbrown
Date: Sun May 31 22:17:38 2009
New Revision: 780520

URL: http://svn.apache.org/viewvc?rev=780520&view=rev
Log:
Implement ArrayList natively (not using java.util.ArrayList); implement LinkedList; remove Sequence.Search and Sequence.Sort classes and move functionality to static methods in ArrayList; eliminate support for setting comparator in EnumList; add static utility methods to JSONSerializer to convert Java types to JSON strings.

Added:
    incubator/pivot/trunk/core/test/pivot/core/test/ArrayListTest.java
    incubator/pivot/trunk/core/test/pivot/core/test/EnumListTest.java
    incubator/pivot/trunk/core/test/pivot/core/test/LinkedListTest.java
Modified:
    incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java
    incubator/pivot/trunk/core/src/pivot/collections/EnumList.java
    incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java
    incubator/pivot/trunk/core/src/pivot/collections/LinkedList.java
    incubator/pivot/trunk/core/src/pivot/collections/Sequence.java
    incubator/pivot/trunk/core/src/pivot/collections/adapter/ListAdapter.java
    incubator/pivot/trunk/core/src/pivot/serialization/JSONSerializer.java
    incubator/pivot/trunk/core/src/pivot/util/ListenerList.java
    incubator/pivot/trunk/demos/src/pivot/demos/million/LargeData.java
    incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java
    incubator/pivot/trunk/tutorials/src/pivot/tutorials/text/Text.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/ListView.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/SpanSequence.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/TableView.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/TreeView.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/TextAreaSkin.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/text/Element.java

Modified: incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java Sun May 31 22:17:38 2009
@@ -17,9 +17,9 @@
 package pivot.collections;
 
 import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.util.Collections;
+import java.util.Arrays;
 import java.util.Comparator;
+import java.util.ConcurrentModificationException;
 import java.util.Iterator;
 
 import pivot.util.ListenerList;
@@ -28,50 +28,111 @@
  * Implementation of the {@link List} interface that is backed by an
  * array.
  * <p>
- * TODO We're temporarily using a java.util.ArrayList to back this list.
- * Eventually, we'll replace this with an internal array representation.
+ * NOTE This class is not thread-safe. For concurrent access, use a
+ * {@link pivot.collections.concurrent.SynchronizedList}.
  *
  * @author gbrown
  */
 public class ArrayList<T> implements List<T>, Serializable {
+    private class ItemIterator implements Iterator<T> {
+        private int index = 0;
+        private int length;
+
+        public ItemIterator() {
+            length = ArrayList.this.length;
+        }
+
+        public boolean hasNext() {
+            return index < getLength();
+        }
+
+        public T next() {
+            if (length != ArrayList.this.length) {
+                throw new ConcurrentModificationException();
+            }
+
+            return get(index++);
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
     private static final long serialVersionUID = 0;
 
-    protected java.util.ArrayList<T> arrayList = null;
+    private Object[] items;
+    private int length = 0;
 
     private Comparator<T> comparator = null;
     private transient ListListenerList<T> listListeners = new ListListenerList<T>();
 
     public ArrayList() {
-        arrayList = new java.util.ArrayList<T>();
+        items = new Object[10];
     }
 
-    public ArrayList(T[] items) {
-        arrayList = new java.util.ArrayList<T>(items.length);
-        for (int i = 0; i < items.length; i++) {
-            arrayList.add(items[i]);
+    public ArrayList(Comparator<T> comparator) {
+        this();
+        this.comparator = comparator;
+    }
+
+    public ArrayList(int capacity) {
+        if (capacity < 0) {
+            throw new IllegalArgumentException();
         }
+
+        items = new Object[capacity];
     }
 
-    public ArrayList(Sequence<T> sequence) {
-        this(sequence, 0, sequence.getLength());
+    public ArrayList(T[] items) {
+        this(items, 0, items.length);
     }
 
-    public ArrayList(Sequence<T> sequence, int index, int count) {
-        arrayList = new java.util.ArrayList<T>(count);
+    public ArrayList(T[] items, int index, int count) {
+        if (items == null) {
+            throw new IllegalArgumentException();
+        }
+
+        if (count < 0) {
+            throw new IllegalArgumentException();
+        }
 
-        for (int i = index, n = index + count; i < n; i++) {
-            T item = sequence.get(i);
-            arrayList.add(item);
+        if (index < 0
+            || index + count > items.length) {
+            throw new IndexOutOfBoundsException();
         }
+
+        this.items = new Object[count];
+        System.arraycopy(items, index, this.items, 0, count);
+
+        length = count;
     }
 
-    public ArrayList(Comparator<T> comparator) {
-        arrayList = new java.util.ArrayList<T>();
-        this.comparator = comparator;
+    public ArrayList(Sequence<T> items) {
+        this(items, 0, items.getLength());
     }
 
-    public ArrayList(int initialCapacity) {
-        arrayList = new java.util.ArrayList<T>(initialCapacity);
+    public ArrayList(Sequence<T> items, int index, int count) {
+        if (items == null) {
+            throw new IllegalArgumentException();
+        }
+
+        if (count < 0) {
+            throw new IllegalArgumentException();
+        }
+
+        if (index < 0
+            || index + count > items.getLength()) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        this.items = new Object[count];
+
+        for (int i = 0; i < count; i++) {
+            this.items[i] = items.get(index + i);
+        }
+
+        length = count;
     }
 
     public int add(T item) {
@@ -79,48 +140,71 @@
 
         if (comparator == null) {
             index = getLength();
+            insert(item, index);
         }
         else {
             // Perform a binary search to find the insertion point
-            index = Search.binarySearch(this, item, comparator);
+            index = binarySearch(this, item, comparator);
             if (index < 0) {
                 index = -(index + 1);
             }
-        }
-
-        arrayList.add(index, item);
 
-        listListeners.itemInserted(this, index);
+            insert(item, index, false);
+        }
 
         return index;
     }
 
     public void insert(T item, int index) {
+        insert(item, index, true);
+    }
+
+    private void insert(T item, int index, boolean validate) {
+        if (index < 0
+            || index > length) {
+            throw new IndexOutOfBoundsException();
+        }
+
         if (comparator != null
-            && Search.binarySearch(this, item, comparator) != -(index + 1)) {
+            && validate
+            && binarySearch(this, item, comparator) != -(index + 1)) {
             throw new IllegalArgumentException("Illegal insertion point.");
         }
 
-        arrayList.add(index, item);
+        // Insert item
+        ensureCapacity(length + 1);
+        System.arraycopy(items, index, items, index + 1, length - index);
+        items[index] = item;
+
+        length++;
 
         listListeners.itemInserted(this, index);
     }
 
+    @SuppressWarnings("unchecked")
     public T update(int index, T item) {
-        if (comparator != null
-            && Search.binarySearch(this, item, comparator) != index) {
-            throw new IllegalArgumentException("Illegal item modification.");
+        if (index < 0
+            || index >= length) {
+            throw new IndexOutOfBoundsException();
         }
 
-        T previousItem = arrayList.get(index);
-        arrayList.set(index, item);
+        T previousItem = (T)items[index];
+
+        if (previousItem != item) {
+            if (comparator != null
+                && binarySearch(this, item, comparator) != index) {
+                throw new IllegalArgumentException("Illegal item modification.");
+            }
+
+            items[index] = item;
 
-        listListeners.itemUpdated(this, index, previousItem);
+            listListeners.itemUpdated(this, index, previousItem);
+        }
 
         return previousItem;
     }
 
-    public int remove (T item) {
+    public int remove(T item) {
         int index = indexOf(item);
 
         if (index == -1) {
@@ -132,39 +216,84 @@
         return index;
     }
 
+    @SuppressWarnings("unchecked")
     public Sequence<T> remove(int index, int count) {
-        ArrayList<T> removed = new ArrayList<T>();
-
-        // Remove the items from the array list
-        // TODO Allocate the array list size first, or use a linked list
-        for (int i = count - 1; i >= 0; i--) {
-            removed.insert(arrayList.remove(index + i), 0);
+        if (index < 0
+            || index + count > length) {
+            throw new IndexOutOfBoundsException();
         }
 
-        listListeners.itemsRemoved(this, index, removed);
+        ArrayList<T> removed = new ArrayList<T>((T[])items, index, count);
+
+        // Remove items
+        if (count > 0) {
+            int end = index + count;
+            System.arraycopy(items, index + count, items, index, length - end);
+
+            length -= count;
+
+            // Clear any orphaned references
+            for (int i = length, n = length + count; i < n; i++) {
+                items[i] =  null;
+            }
+
+            listListeners.itemsRemoved(this, index, removed);
+        }
 
         return removed;
     }
 
     public void clear() {
-        arrayList.clear();
-        listListeners.listCleared(this);
+        if (length > 0) {
+            for (int i = 0; i < length; i++) {
+                items[i] = null;
+            }
+
+            length = 0;
+
+            listListeners.listCleared(this);
+        }
     }
 
+    @SuppressWarnings("unchecked")
     public T get(int index) {
-        return arrayList.get(index);
+        if (index < 0
+            || index >= length) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        return (T)items[index];
     }
 
+    @SuppressWarnings("unchecked")
     public int indexOf(T item) {
         int index = -1;
+
         if (comparator == null) {
-            // TODO Ensure that we use the equals() method here when
-            // managing list contents internally
-            index = arrayList.indexOf(item);
+            int i = 0;
+            while (i < length) {
+                if (item == null) {
+                    if (items[i] == null) {
+                        break;
+                    }
+                } else {
+                    if (item.equals(items[i])) {
+                        break;
+                    }
+                }
+
+                i++;
+            }
+
+            if (i < length) {
+                index = i;
+            } else {
+                index = -1;
+            }
         }
         else {
             // Perform a binary search to find the index
-            index = Search.binarySearch(this, item, comparator);
+            index = binarySearch(this, item, comparator);
             if (index < 0) {
                 index = -1;
             }
@@ -174,38 +303,53 @@
     }
 
     public int getLength() {
-        return arrayList.size();
+        return length;
     }
 
-    @SuppressWarnings("unchecked")
-    public T[] toArray() {
-        T[] array = null;
+    public void trimToSize() {
+        Object[] items = new Object[length];
+        System.arraycopy(this.items, 0, items, 0, length);
 
-        int n = getLength();
-        if (n > 0) {
-            Class<?> type = get(0).getClass();
-            array = (T[])Array.newInstance(type, n);
+        this.items = items;
+        length = items.length;
+    }
 
-            for (int i = 0; i < n; i++) {
-                array[i] = get(i);
-            }
+    public void ensureCapacity(int capacity) {
+        if (capacity > items.length) {
+            capacity = Math.max(this.items.length * 3 / 2, capacity);
+            Object[] items = new Object[capacity];
+            System.arraycopy(this.items, 0, items, 0, length);
+
+            this.items = items;
         }
+    }
 
-        return array;
+    public int getCapacity() {
+        return items.length;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T[] toArray() {
+        Object[] array = new Object[length];
+        System.arraycopy(items, 0, array, 0, length);
+
+        return (T[])array;
     }
 
     public Comparator<T> getComparator() {
         return comparator;
     }
 
+    @SuppressWarnings("unchecked")
     public void setComparator(Comparator<T> comparator) {
         Comparator<T> previousComparator = this.comparator;
 
         if (previousComparator != comparator) {
             if (comparator != null) {
-                Collections.sort(arrayList, comparator);
+                sort(this, comparator);
             }
 
+            // Set the new comparator
             this.comparator = comparator;
 
             listListeners.comparatorChanged(this, previousComparator);
@@ -213,15 +357,7 @@
     }
 
     public Iterator<T> iterator() {
-        // TODO Return a fail-fast iterator, similar to java.util.ArrayList
-        // We can use a modificationCount value; each call to a mutator method can
-        // increment the count - the iterator will retain a copy of the modifier count
-        // when it is created. We can potentially reset the modifier count when all
-        // outstanding iterators are finalized.
-
-        // TODO Alternatively, we could just return an immutable iterator
-
-        return arrayList.iterator();
+        return new ItemIterator();
     }
 
     public ListenerList<ListListener<T>> getListListeners() {
@@ -245,4 +381,72 @@
 
         return sb.toString();
     }
+
+    public static <T> void sort(ArrayList<T> arrayList, Comparator<T> comparator) {
+        sort(arrayList, 0, arrayList.getLength(), comparator);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> void sort(ArrayList<T> arrayList, int from, int to, Comparator<T> comparator) {
+        if (arrayList == null
+            || comparator == null) {
+            throw new IllegalArgumentException();
+        }
+
+        Arrays.sort((T[])arrayList.items, from, to, comparator);
+    }
+
+    public static <T extends Comparable<? super T>> int binarySearch(ArrayList<T> arrayList,
+        T item) {
+        Comparator<T> comparator = new Comparator<T>() {
+            public int compare(T t1, T t2) {
+                return t1.compareTo(t2);
+            }
+        };
+
+        return binarySearch(arrayList, item, comparator);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> int binarySearch(ArrayList<T> arrayList, T item,
+        final Comparator<T> comparator) {
+        if (arrayList == null
+            || item == null
+            || comparator == null) {
+            throw new IllegalArgumentException();
+        }
+
+        // TODO Use java.util.Arrays#binarySearch() when Java 6 is available
+        // on Mac OS X
+        // int index = Arrays.binarySearch((T[])arrayList.items, 0, arrayList.length, item, comparator);
+        int index = binarySearch((T[])arrayList.items, arrayList.length, item, comparator);
+
+        return index;
+    }
+
+    // TODO Remove this method when it is no longer needed; see above
+    private static <T> int binarySearch(T[] array, int length, T item, Comparator<T> comparator) {
+        int low = 0;
+        int high = length - 1;
+
+        while (low <= high) {
+            int mid = (low + high) >> 1;
+            T midVal = array[mid];
+            int cmp = comparator.compare(midVal, item);
+
+            if (cmp < 0) {
+               low = mid + 1;
+            }
+            else if (cmp > 0) {
+               high = mid - 1;
+            }
+            else {
+               // Item found
+               return mid;
+            }
+        }
+
+        // Item not found
+        return -(low + 1);
+    }
 }

Modified: incubator/pivot/trunk/core/src/pivot/collections/EnumList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/EnumList.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/EnumList.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/EnumList.java Sun May 31 22:17:38 2009
@@ -16,8 +16,7 @@
  */
 package pivot.collections;
 
-import java.lang.reflect.Array;
-import java.util.Arrays;
+import java.io.Serializable;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
@@ -28,26 +27,31 @@
 import pivot.util.ListenerList;
 
 /**
- * Implementation of the {@link List} interface that is backed by an
- * <tt>enum</tt>.
+ * Implementation of the {@link List} interface that is backed by an enum.
  *
  * @author tvolkert
+ * @author gbrown
  */
-public class EnumList<E extends Enum<E>> implements List<E> {
-    private E[] elements;
+public class EnumList<E extends Enum<E>> implements List<E>, Serializable {
+    private static final long serialVersionUID = 0;
+
     private Class<E> enumClass;
+    private E[] elements;
 
-    private Comparator<E> comparator = null;
-    private ListListenerList<E> listListeners = null;
+    private transient ListListenerList<E> listListeners = null;
 
     public EnumList() {
-        this.enumClass = null;
-        elements = null;
+        this(null);
     }
 
     public EnumList(Class<E> enumClass) {
         this.enumClass = enumClass;
-        elements = enumClass.getEnumConstants();
+
+        if (enumClass == null) {
+            elements = null;
+        } else {
+            elements = enumClass.getEnumConstants();
+        }
     }
 
     public Class<E> getEnumClass() {
@@ -55,7 +59,7 @@
     }
 
     public void setEnumClass(Class<E> enumClass) {
-        Class <E> previousEnumClass = this.enumClass;
+        Class<E> previousEnumClass = this.enumClass;
 
         if (enumClass != previousEnumClass) {
             this.enumClass = enumClass;
@@ -74,14 +78,9 @@
             elements = enumClass.getEnumConstants();
 
             if (elements != null) {
-                // Sort if necessary
-                if (comparator != null) {
-                    Arrays.sort(elements, comparator);
-                }
-
                 // Notify listeners of the new elements
                 if (listListeners != null) {
-                    for (int i = 0, n = elements.length; i < n; i++) {
+                    for (int i = 0; i < elements.length; i++) {
                         listListeners.itemInserted(this, i);
                     }
                 }
@@ -90,12 +89,15 @@
     }
 
     @SuppressWarnings("unchecked")
-    public final void setEnumClass(String enumClass) {
+    public final void setEnumClass(String enumClassName) {
+        Class<E> enumClass;
         try {
-            setEnumClass((Class<E>)Class.forName(enumClass));
-        } catch (ClassNotFoundException ex) {
-            throw new IllegalArgumentException(ex);
+            enumClass = (Class<E>)Class.forName(enumClassName);
+        } catch (ClassNotFoundException exception) {
+            throw new IllegalArgumentException(exception);
         }
+
+        setEnumClass(enumClass);
     }
 
     public int add(E item) {
@@ -130,17 +132,10 @@
         int index = -1;
 
         if (elements != null) {
-            if (comparator == null) {
-                for (int i = 0, n = elements.length; i < n && index == -1; i++) {
-                    if (elements[i] == item) {
-                        index = i;
-                    }
-                }
-            } else {
-                // Perform a binary search to find the index
-                index = Search.binarySearch(this, item, comparator);
-                if (index < 0) {
-                    index = -1;
+            for (int i = 0; i < elements.length; i++) {
+                if (elements[i] == item) {
+                    index = i;
+                    break;
                 }
             }
         }
@@ -154,40 +149,22 @@
 
     @SuppressWarnings("unchecked")
     public E[] toArray() {
-        E[] array = null;
+        Object[] array = null;
 
         if (elements != null) {
-            int n = elements.length;
-            if (n > 0) {
-                Class<?> type = elements[0].getClass();
-                array = (E[])Array.newInstance(type, n);
-                System.arraycopy(elements, 0, array, 0, n);
-            }
+            array = new Object[elements.length];
+            System.arraycopy(elements, 0, array, 0, elements.length);
         }
 
-        return array;
+        return (E[])array;
     }
 
     public Comparator<E> getComparator() {
-        return comparator;
+        return null;
     }
 
     public void setComparator(Comparator<E> comparator) {
-        Comparator<E> previousComparator = this.comparator;
-
-        if (previousComparator != comparator) {
-            this.comparator = comparator;
-
-            // Perform the sort
-            if (comparator != null && elements != null) {
-                Arrays.sort(elements, comparator);
-            }
-
-            // Notify listeners
-            if (listListeners != null) {
-                listListeners.comparatorChanged(this, previousComparator);
-            }
-        }
+        throw new UnsupportedOperationException();
     }
 
     public Iterator<E> iterator() {

Modified: incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java Sun May 31 22:17:38 2009
@@ -24,7 +24,7 @@
 
 /**
  * Implementation of the {@link Set} interface that is backed by a bitfield
- * representing <tt>enum</tt> values. Values are mapped to the bitfield by their
+ * representing enum> values. Values are mapped to the bitfield by their
  * ordinal value.
  */
 public class EnumSet<E extends Enum<E>> implements Set<E>, Serializable {

Modified: incubator/pivot/trunk/core/src/pivot/collections/LinkedList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/LinkedList.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/LinkedList.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/LinkedList.java Sun May 31 22:17:38 2009
@@ -17,8 +17,10 @@
 package pivot.collections;
 
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 import pivot.util.ListenerList;
 
@@ -26,71 +28,355 @@
  * Implementation of the {@link List} interface that is backed by a linked
  * list.
  * <p>
- * TODO This class is currently incomplete.
+ * NOTE This class is not thread-safe. For concurrent access, use a
+ * {@link pivot.collections.concurrent.SynchronizedList}.
  */
 public class LinkedList<T> implements List<T>, Serializable {
+    // Node containing an item in the list
+    private class Node {
+        private Node previous;
+        private Node next;
+        private T item;
+
+        public Node(Node previous, Node next, T item) {
+            this.previous = previous;
+            this.next = next;
+            this.item = item;
+        }
+    }
+
+    // Node iterator
+    private class NodeIterator implements Iterator<T> {
+        private Node node;
+
+        public NodeIterator() {
+            this.node = first;
+        }
+
+        public boolean hasNext() {
+            return (node != null);
+        }
+
+        public T next() {
+            if (node == null) {
+                throw new NoSuchElementException();
+            }
+
+            T item = node.item;
+            node = node.next;
+
+            return item;
+        }
+
+        public void remove() {
+            // Unlink this node from its predecessor and successor
+            if (node.previous != null) {
+                node.previous.next = node.next;
+            }
+
+            if (node.next != null) {
+                node.next.previous = node.previous;
+            }
+        }
+    }
+
     private static final long serialVersionUID = 0;
 
+    private Node first = null;
+    private Node last = null;
+    private int length = 0;
+
+    private Comparator<T> comparator = null;
+    private transient ListListenerList<T> listListeners = new ListListenerList<T>();
+
     public int add(T item) {
-        // TODO
-        return 0;
+        int index;
+        if (comparator == null) {
+            // Append to the tail
+            index = length;
+            insert(item, index);
+        } else {
+            // Find the insertion point
+            index = 0;
+            NodeIterator nodeIterator = new NodeIterator();
+            while (nodeIterator.hasNext()
+                && comparator.compare(item, nodeIterator.next()) > 0) {
+                index++;
+            }
+
+            if (nodeIterator.hasNext()
+                && index > 0) {
+                // Insert the new node here
+                Node node = new Node(nodeIterator.node, nodeIterator.node.next, item);
+                nodeIterator.node.next = node;
+                node.next.previous = node;
+                length++;
+            } else {
+                // Insert at the head or append to the tail
+                insert(item, index, false);
+            }
+        }
+
+        return index;
     }
 
     public void insert(T item, int index) {
-        // TODO Auto-generated method stub
+        insert(item, index, true);
     }
 
-    public T update(int index, T item) {
-        // TODO Auto-generated method stub
-        return null;
+    private void insert(T item, int index, boolean validate) {
+        if (index < 0
+            || index > length) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (length == 0) {
+            Node node = new Node(null, null, item);
+            first = node;
+            last = node;
+        } else {
+            Node next = (index == length) ? null : getNode(index);
+            Node previous = (next == null) ? last : next.previous;
+
+            if (comparator != null) {
+                // Ensure that the new item is greater or equal to its
+                // predecessor and less than or equal to its successor
+                if ((previous != null
+                        && comparator.compare(item, previous.item) == -1)
+                    || (next != null
+                        && comparator.compare(item, next.item) == 1)) {
+                    throw new IllegalArgumentException("Illegal item modification.");
+                }
+            }
+
+            Node node = new Node(previous, next, item);
+            if (previous == null) {
+                first = node;
+            } else {
+                previous.next = node;
+            }
+
+            if (next == null) {
+                last = node;
+            } else {
+                next.previous = node;
+            }
+        }
+
+        // Update length and notify listeners
+        length++;
+        listListeners.itemInserted(this, index);
     }
 
-    public int remove (T item) {
-        // TODO
-        return -1;
+    public T update(int index, T item) {
+        if (index < 0
+            || index >= length) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        // Get the previous item at index
+        Node node = getNode(index);
+        T previousItem = node.item;
+
+        if (previousItem != item) {
+            if (comparator != null) {
+                // Ensure that the new item is greater or equal to its
+                // predecessor and less than or equal to its successor
+                if ((node.previous != null
+                        && comparator.compare(item, node.previous.item) == -1)
+                    || (node.next != null
+                        && comparator.compare(item, node.next.item) == 1)) {
+                    throw new IllegalArgumentException("Illegal item modification.");
+                }
+            }
+
+            // Update the item
+            node.item = item;
+
+            listListeners.itemUpdated(this, index, previousItem);
+        }
+
+        return previousItem;
+    }
+
+    public int remove(T item) {
+        int index = 0;
+
+        NodeIterator nodeIterator = new NodeIterator();
+        while (nodeIterator.hasNext()) {
+            if (nodeIterator.next() == item) {
+                nodeIterator.remove();
+                break;
+            } else {
+                index++;
+            }
+        }
+
+        if (!nodeIterator.hasNext()) {
+            index = -1;
+        }
+
+        return index;
     }
 
     public Sequence<T> remove(int index, int count) {
-        // TODO Auto-generated method stub
-        return null;
+        if (index < 0
+            || index + count > length) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        LinkedList<T> removed = new LinkedList<T>();
+
+        if (count > 0) {
+            // Identify the bounding nodes and build the removed item list
+            Node start = getNode(index);
+            Node end = start;
+            for (int i = 0; i < count; i++) {
+                removed.add(end.item);
+                end = end.next;
+            }
+
+            end = end.previous;
+
+            // Decouple the nodes from the list
+            if (start.previous != null) {
+                start.previous.next = end.next;
+            }
+
+            if (index + count == length) {
+                last = start.previous;
+            }
+
+            if (end.next != null) {
+                end.next.previous = start.previous;
+            }
+
+            if (index == 0) {
+                first = end.next;
+            }
+
+            start.previous = null;
+            end.next = null;
+
+            // Update length and notify listeners
+            length -= count;
+            listListeners.itemsRemoved(this, index, removed);
+        }
+
+        return removed;
     }
 
     public void clear() {
-        // TODO
+        if (length > 0) {
+            first = null;
+            last = null;
+            length = 0;
+
+            listListeners.listCleared(this);
+        }
     }
 
     public T get(int index) {
-        // TODO Auto-generated method stub
-        return null;
+        if (index < 0
+            || index >= length) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        T item;
+        if (index == 0) {
+            item = first.item;
+        } else if (index == length - 1) {
+            item = last.item;
+        } else {
+            Node node = getNode(index);
+            item = node.item;
+        }
+
+        return item;
+    }
+
+    private Node getNode(int index) {
+        Node node = first;
+        for (int i = 0; i < index; i++) {
+            node = node.next;
+        }
+
+        return node;
     }
 
     public int indexOf(T item) {
-        // TODO
-        return -1;
+        int index = 0;
+
+        NodeIterator nodeIterator = new NodeIterator();
+        while (nodeIterator.hasNext()) {
+            if (nodeIterator.next() == item) {
+                break;
+            } else {
+                index++;
+            }
+        }
+
+        if (!nodeIterator.hasNext()) {
+            index = -1;
+        }
+
+        return index;
     }
 
     public int getLength() {
-        // TODO Auto-generated method stub
-        return 0;
+        return length;
     }
 
     public Comparator<T> getComparator() {
-        // TODO Auto-generated method stub
-        return null;
+        return comparator;
     }
 
+    @SuppressWarnings("unchecked")
     public void setComparator(Comparator<T> comparator) {
-        // TODO Auto-generated method stub
+        Comparator<T> previousComparator = this.comparator;
+
+        if (previousComparator != comparator) {
+            if (comparator != null) {
+                // Copy the nodes into an array and sort
+                T[] array = (T[])new Object[length];
+
+                int i = 0;
+                for (T item : this) {
+                    array[i++] = item;
+                }
+
+                Arrays.sort(array, comparator);
+
+                // Rebuild the node list
+                first = null;
+
+                Node node = null;
+                for (i = 0; i < length; i++) {
+                    Node previousNode = node;
+                    node = new Node(previousNode, null, array[i]);
+
+                    if (previousNode == null) {
+                        first = node;
+                    } else {
+                        previousNode.next = node;
+                    }
+                }
+
+                last = node;
+            }
+
+            // Set the new comparator
+            this.comparator = comparator;
 
+            listListeners.comparatorChanged(this, previousComparator);
+        }
     }
 
     public Iterator<T> iterator() {
-        // TODO Auto-generated method stub
-        return null;
+        return new NodeIterator();
     }
 
     public ListenerList<ListListener<T>> getListListeners() {
-        // TODO Auto-generated method stub
-        return null;
+        return listListeners;
     }
 }

Modified: incubator/pivot/trunk/core/src/pivot/collections/Sequence.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/Sequence.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/Sequence.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/Sequence.java Sun May 31 22:17:38 2009
@@ -16,7 +16,6 @@
  */
 package pivot.collections;
 
-import java.util.Comparator;
 import java.util.Iterator;
 
 import pivot.util.ImmutableIterator;
@@ -334,175 +333,6 @@
     }
 
     /**
-     * Contains utility methods for searching sequences.
-     *
-     * @author gbrown, tvolkert
-     */
-    public static class Search {
-        /**
-         * Performs a binary search of a sequence for the given comparable item.
-         * See {@link #binarySearch(Sequence, Object, Comparator)}.
-         */
-        public static <T extends Comparable<? super T>> int binarySearch(Sequence<T> sequence, T item) {
-            Comparator<T> comparator = new Comparator<T>() {
-                public int compare(T t1, T t2) {
-                    return t1.compareTo(t2);
-                }
-            };
-
-            return binarySearch(sequence, item, comparator);
-        }
-
-        /**
-         * Performs a binary search of a sequence for the given item.
-         *
-         * @param sequence
-         * The sequence to search. If the sequence is not sorted, the behavior
-         * is undefined.
-         *
-         * @param item
-         * The item to search for.
-         *
-         * @param comparator
-         * Comparator that determines element order.
-         *
-         * @return
-         * The index of <tt>item</tt>, if it is contained in the sequence;
-         * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The insertion
-         * point is defined as the point at which the item would be inserted
-         * into the sequence: the index of the first element greater than
-         * <tt>item</tt>, or <tt>sequence.getLength()</tt>, if all items in the
-         * sequence are less than <tt>item</tt>. Note that this guarantees that
-         * the return value will be greater than 0 if and only if the item is
-         * found.
-         * <p>
-         * If the sequence contains multiple elements equal to the specified
-         * item, there is no guarantee which one will be found.
-         */
-        public static <T> int binarySearch(Sequence<T> sequence, T item,
-            Comparator<T> comparator) {
-            int low = 0;
-            int high = sequence.getLength() - 1;
-
-            while (low <= high) {
-                int mid = (low + high) >> 1;
-                T midVal = sequence.get(mid);
-                int cmp = comparator.compare(midVal, item);
-
-                if (cmp < 0) {
-                   low = mid + 1;
-                }
-                else if (cmp > 0) {
-                   high = mid - 1;
-                }
-                else {
-                   // Item found
-                   return mid;
-                }
-            }
-
-            // Item not found
-            return -(low + 1);
-        }
-
-        /**
-         * Performs a linear search of a sequence for the given comparable item.
-         * See {@link #linearSearch(Sequence, Object, Comparator)}.
-         */
-        public static <T extends Comparable<? super T>> int linearSearch(Sequence<T> sequence, T item) {
-            Comparator<T> comparator = new Comparator<T>() {
-                public int compare(T t1, T t2) {
-                    return t1.compareTo(t2);
-                }
-            };
-
-            return linearSearch(sequence, item, comparator);
-        }
-
-        /**
-         * Performs a linear search of a sequence for the given item.
-         *
-         * @param sequence
-         * The sequence to search.
-         *
-         * @param item
-         * The item to search for.
-         *
-         * @param comparator
-         * Comparator that will be used to determine logical equality.
-         *
-         * @return
-         * The index of <tt>item</tt>, if it is contained in the sequence;
-         * otherwise, <tt>-1</tt>.
-         * <p>
-         * If the sequence contains multiple elements equal to the specified
-         * item, this will return the first occurrence.
-         */
-        public static <T> int linearSearch(Sequence<T> sequence, T item,
-            Comparator<T> comparator) {
-            int index = -1;
-
-            for (int i = 0, n = sequence.getLength(); i < n; i++) {
-                T current = sequence.get(i);
-
-                if (comparator.compare(current, item) == 0) {
-                    // Item found
-                    index = i;
-                    break;
-                }
-            }
-
-            return index;
-        }
-    }
-
-    /**
-     * Contains utility methods for sorting sequences.
-     *
-     * @author gbrown
-     */
-    public static class Sort {
-        /**
-         * Performs a quicksort on the sequence for the given comparable type.
-         * See {@link #quickSort(Sequence, Comparator)}.
-         */
-        public static <T extends Comparable<? super T>> void quickSort(Sequence<T> sequence) {
-            Comparator<T> comparator = new Comparator<T>() {
-                public int compare(T t1, T t2) {
-                    return t1.compareTo(t2);
-                }
-            };
-
-            quickSort(sequence, comparator);
-        }
-
-        /**
-         * Performs a quicksort on the sequence.
-         *
-         * @param sequence
-         * The sequence to sort.
-         *
-         * @param comparator
-         * Comparator that determines element order.
-         */
-        public static <T> void quickSort(Sequence<T> sequence, Comparator<T> comparator) {
-            // TODO Implement internally rather than copying to java.util.ArrayList
-
-            java.util.ArrayList<T> arrayList = new java.util.ArrayList<T>(sequence.getLength());
-
-            for (int i = 0, n = sequence.getLength(); i < n; i++) {
-                arrayList.add(sequence.get(i));
-            }
-
-            java.util.Collections.sort(arrayList, comparator);
-
-            for (int i = 0, n = arrayList.size(); i < n; i++) {
-                sequence.update(i, arrayList.get(i));
-            }
-        }
-    }
-
-    /**
      * Adds an item to the sequence.
      *
      * @param item

Modified: incubator/pivot/trunk/core/src/pivot/collections/adapter/ListAdapter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/adapter/ListAdapter.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/adapter/ListAdapter.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/adapter/ListAdapter.java Sun May 31 22:17:38 2009
@@ -55,7 +55,7 @@
         }
         else {
             // Perform a binary search to find the insertion point
-            index = Search.binarySearch(this, item, comparator);
+            index = Collections.binarySearch(list, item, comparator);
             if (index < 0) {
                 index = -(index + 1);
             }
@@ -69,7 +69,7 @@
 
     public void insert(T item, int index) {
         if (comparator != null
-            && Search.binarySearch(this, item, comparator) != -(index + 1)) {
+            && Collections.binarySearch(list, item, comparator) != -(index + 1)) {
             throw new IllegalArgumentException("Illegal insertion point.");
         }
 
@@ -80,7 +80,7 @@
 
     public T update(int index, T item) {
         if (comparator != null
-            && Search.binarySearch(this, item, comparator) != index) {
+            && Collections.binarySearch(list, item, comparator) != index) {
             throw new IllegalArgumentException("Illegal item modification.");
         }
 

Modified: incubator/pivot/trunk/core/src/pivot/serialization/JSONSerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/serialization/JSONSerializer.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/serialization/JSONSerializer.java (original)
+++ incubator/pivot/trunk/core/src/pivot/serialization/JSONSerializer.java Sun May 31 22:17:38 2009
@@ -25,6 +25,7 @@
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.StringReader;
+import java.io.StringWriter;
 import java.io.Writer;
 import java.nio.charset.Charset;
 
@@ -37,8 +38,6 @@
 /**
  * Implementation of the {@link Serializer} interface that reads data from
  * and writes data to a JavaScript Object Notation (JSON) file.
- * <p>
- * TODO Wrap reader in a CountingReader that tracks line/character index.
  *
  * @author gbrown
  */
@@ -1188,4 +1187,112 @@
     public static Map<String, ?> parseMap(String json) {
         return (Map<String, ?>)parse(json);
     }
+
+    /**
+     * Converts a object to a JSON string representation.
+     *
+     * @param value
+     * The object to convert.
+     *
+     * @return
+     * The resulting JSON string.
+     */
+    public static String toString(Object value)
+        throws SerializationException {
+        JSONSerializer jsonSerializer = new JSONSerializer();
+        StringWriter writer = new StringWriter();
+
+        try {
+            jsonSerializer.writeObject(value, writer);
+        } catch(IOException exception) {
+            throw new RuntimeException(exception);
+        }
+
+        return writer.toString();
+    }
+
+    /**
+     * Converts a string to a JSON string representation.
+     *
+     * @param value
+     * The object to convert.
+     *
+     * @return
+     * The resulting JSON string.
+     */
+    public static String toString(String value) {
+        try {
+            return toString((Object)value);
+        } catch(SerializationException exception) {
+            throw new RuntimeException(exception);
+        }
+    }
+
+    /**
+     * Converts a number to a JSON string representation.
+     *
+     * @param value
+     * The object to convert.
+     *
+     * @return
+     * The resulting JSON string.
+     */
+    public static String toString(Number value) {
+        try {
+            return toString((Object)value);
+        } catch(SerializationException exception) {
+            throw new RuntimeException(exception);
+        }
+    }
+
+    /**
+     * Converts a boolean to a JSON string representation.
+     *
+     * @param value
+     * The object to convert.
+     *
+     * @return
+     * The resulting JSON string.
+     */
+    public static String toString(Boolean value) {
+        try {
+            return toString((Object)value);
+        } catch(SerializationException exception) {
+            throw new RuntimeException(exception);
+        }
+    }
+
+    /**
+     * Converts a list to a JSON string representation.
+     *
+     * @param value
+     * The object to convert.
+     *
+     * @return
+     * The resulting JSON string.
+     */
+    public static String toString(List<?> value) {
+        try {
+            return toString((Object)value);
+        } catch(SerializationException exception) {
+            throw new RuntimeException(exception);
+        }
+    }
+
+    /**
+     * Converts a map to a JSON string representation.
+     *
+     * @param value
+     * The object to convert.
+     *
+     * @return
+     * The resulting JSON string.
+     */
+    public static String toString(Map<String, ?> value) {
+        try {
+            return toString((Object)value);
+        } catch(SerializationException exception) {
+            throw new RuntimeException(exception);
+        }
+    }
 }

Modified: incubator/pivot/trunk/core/src/pivot/util/ListenerList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/util/ListenerList.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/util/ListenerList.java (original)
+++ incubator/pivot/trunk/core/src/pivot/util/ListenerList.java Sun May 31 22:17:38 2009
@@ -28,11 +28,7 @@
  * @author gbrown
  */
 public abstract class ListenerList<T> implements Iterable<T> {
-    /**
-     * Represents a node in the linked list of event listeners.
-     *
-     * @author gbrown
-     */
+    // Node containing a listener in the list
     private class Node {
         private Node previous;
         private Node next;
@@ -45,16 +41,12 @@
         }
     }
 
-    /**
-     * Listener list iterator.
-     *
-     * @author gbrown
-     */
+    // Node iterator
     private class NodeIterator implements Iterator<T> {
         private Node node;
 
-        public NodeIterator(Node node) {
-            this.node = node;
+        public NodeIterator() {
+            this.node = first;
         }
 
         public boolean hasNext() {
@@ -77,9 +69,8 @@
         }
     }
 
-    /**
-     * The first node in the list, or <tt>null</tt> if the list is empty.
-     */
+    // First node in the list (we don't maintain a reference to the last
+    // node, since we need to walk the list looking for duplicates on add)
     private Node first = null;
 
     /**
@@ -147,6 +138,6 @@
     }
 
     public Iterator<T> iterator() {
-        return new NodeIterator(first);
+        return new NodeIterator();
     }
 }

Added: incubator/pivot/trunk/core/test/pivot/core/test/ArrayListTest.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/test/pivot/core/test/ArrayListTest.java?rev=780520&view=auto
==============================================================================
--- incubator/pivot/trunk/core/test/pivot/core/test/ArrayListTest.java (added)
+++ incubator/pivot/trunk/core/test/pivot/core/test/ArrayListTest.java Sun May 31 22:17:38 2009
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+package pivot.core.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import pivot.collections.ArrayList;
+import pivot.collections.Sequence;
+
+public class ArrayListTest {
+    @Test
+    public void basicTest() {
+        ArrayList<String> list = new ArrayList<String>();
+        list.insert("B", 0);
+        list.insert("C", 1);
+        list.insert("D", 2);
+        list.insert("A", 0);
+
+        assertEquals(ArrayList.binarySearch(list, "A"), 0);
+
+        list.remove(0, 1);
+        assertEquals(list.get(0), "B");
+        assertEquals(list.getLength(), 3);
+        assertEquals(list.indexOf("C"), 1);
+
+        Sequence<String> removed = list.remove(1, 1);
+        assertNotNull(removed.get(0));
+        assertTrue(removed.get(0).equals("C"));
+
+        list.trimToSize();
+        list.ensureCapacity(10);
+        assertEquals(list.getCapacity(), 10);
+
+        list.insert("E", 1);
+        assertEquals(list.getLength(), 3);
+        assertNotNull(list.get(1));
+        assertTrue(list.get(1).equals("E"));
+    }
+}

Added: incubator/pivot/trunk/core/test/pivot/core/test/EnumListTest.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/test/pivot/core/test/EnumListTest.java?rev=780520&view=auto
==============================================================================
--- incubator/pivot/trunk/core/test/pivot/core/test/EnumListTest.java (added)
+++ incubator/pivot/trunk/core/test/pivot/core/test/EnumListTest.java Sun May 31 22:17:38 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+package pivot.core.test;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import pivot.collections.EnumList;
+
+public class EnumListTest {
+    public enum TestEnum {
+        A,
+        B,
+        C
+    }
+
+    @Test
+    public void basicTest() {
+        EnumList<TestEnum> enumList = new EnumList<TestEnum>(TestEnum.class);
+
+        assertEquals(enumList.get(0), TestEnum.A);
+        assertEquals(enumList.get(1), TestEnum.B);
+        assertEquals(enumList.getLength(), 3);
+    }
+}

Added: incubator/pivot/trunk/core/test/pivot/core/test/LinkedListTest.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/test/pivot/core/test/LinkedListTest.java?rev=780520&view=auto
==============================================================================
--- incubator/pivot/trunk/core/test/pivot/core/test/LinkedListTest.java (added)
+++ incubator/pivot/trunk/core/test/pivot/core/test/LinkedListTest.java Sun May 31 22:17:38 2009
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+package pivot.core.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import pivot.collections.LinkedList;
+import pivot.collections.Sequence;
+import pivot.serialization.JSONSerializer;
+
+public class LinkedListTest {
+    @Test
+    public void basicTest() {
+        LinkedList<String> list = new LinkedList<String>();
+        list.insert("B", 0);
+        list.insert("C", 1);
+        list.insert("D", 2);
+        list.insert("A", 0);
+
+        assertEquals(list.indexOf("A"), 0);
+
+        list.remove(0, 1);
+        assertEquals(list.get(0), "B");
+        assertEquals(list.getLength(), 3);
+        assertEquals(list.indexOf("C"), 1);
+
+        Sequence<String> removed = list.remove(1, 1);
+        assertNotNull(removed.get(0));
+        assertTrue(removed.get(0).equals("C"));
+
+        list.insert("E", 1);
+        assertEquals(list.getLength(), 3);
+        assertNotNull(list.get(1));
+        assertTrue(list.get(1).equals("E"));
+
+        list.update(1, "F");
+        assertNotNull(list.get(1));
+        assertTrue(list.get(1).equals("F"));
+
+        list.insert("G", 0);
+        assertEquals(JSONSerializer.toString(list), "[\"G\", \"B\", \"F\", \"D\"]");
+    }
+}

Modified: incubator/pivot/trunk/demos/src/pivot/demos/million/LargeData.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/pivot/demos/million/LargeData.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/demos/src/pivot/demos/million/LargeData.java (original)
+++ incubator/pivot/trunk/demos/src/pivot/demos/million/LargeData.java Sun May 31 22:17:38 2009
@@ -84,7 +84,7 @@
 
                     CSVSerializer.StreamIterator streamIterator = csvSerializer.getStreamIterator(inputStream);
 
-                    ArrayList<Object> page = new ArrayList<Object>(PAGE_SIZE);
+                    ArrayList<Object> page = new ArrayList<Object>(pageSize);
                     while (streamIterator.hasNext()
                         && !abort) {
                         Object item = streamIterator.next();
@@ -94,9 +94,9 @@
                         i++;
 
                         if (!streamIterator.hasNext()
-                            || page.getLength() == PAGE_SIZE) {
+                            || page.getLength() == pageSize) {
                             ApplicationContext.queueCallback(new AddRowsCallback(page));
-                            page = new ArrayList<Object>(PAGE_SIZE);
+                            page = new ArrayList<Object>(pageSize);
                         }
                     }
                 } finally {
@@ -142,11 +142,11 @@
     @Bind(fieldName="window") private TableViewHeader tableViewHeader;
 
     private CSVSerializer csvSerializer;
+    private int pageSize = 0;
 
     private volatile boolean abort = false;
 
     private static final String BASE_PATH_KEY = "basePath";
-    private static final int PAGE_SIZE = 100;
 
     public LargeData() {
         csvSerializer = new CSVSerializer("ISO-8859-1");
@@ -213,7 +213,12 @@
 
     private void loadData() {
         abort = false;
-        tableView.getTableData().clear();
+
+        int index = fileListButton.getSelectedIndex();
+        int capacity = (int)Math.pow(10, index + 1);
+        tableView.setTableData(new ArrayList<Object>(capacity));
+
+        pageSize = Math.max(capacity / 1000, 100);
 
         String fileName = (String)fileListButton.getSelectedItem();
 

Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java Sun May 31 22:17:38 2009
@@ -400,9 +400,9 @@
                 columns.get(4).setHeaderData(new TableViewHeaderData("D"));
 
                 // Populate table
-                ArrayList<Object> tableData = new ArrayList<Object>();
+                ArrayList<Object> tableData = new ArrayList<Object>(10000);
 
-                for (int i = 0; i < 10000; i++) {
+                for (int i = 0, n = tableData.getCapacity(); i < n; i++) {
                     TableRow tableRow = new TableRow();
 
                     tableRow.put("i", i);

Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/text/Text.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/text/Text.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/text/Text.java (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/text/Text.java Sun May 31 22:17:38 2009
@@ -18,7 +18,6 @@
 
 import pivot.collections.ArrayList;
 import pivot.collections.Dictionary;
-import pivot.collections.Sequence;
 import pivot.wtk.Application;
 import pivot.wtk.DesktopApplicationContext;
 import pivot.wtk.Display;
@@ -38,7 +37,7 @@
         public void charactersInserted(final TextInput textInput, int index, int count) {
             String text = textInput.getText();
 
-            int i = Sequence.Search.binarySearch(states, text,
+            int i = ArrayList.binarySearch(states, text,
                 states.getComparator());
 
             if (i < 0) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/ListView.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/ListView.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/ListView.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/ListView.java Sun May 31 22:17:38 2009
@@ -135,7 +135,7 @@
             int i, n;
 
             // Increment checked indexes
-            i = Sequence.Search.binarySearch(checkedIndexes, index);
+            i = ArrayList.binarySearch(checkedIndexes, index);
             if (i < 0) {
                 i = -(i + 1);
             }
@@ -147,7 +147,7 @@
             }
 
             // Increment disabled indexes
-            i = Sequence.Search.binarySearch(disabledIndexes, index);
+            i = ArrayList.binarySearch(disabledIndexes, index);
             if (i < 0) {
                 i = -(i + 1);
             }
@@ -171,7 +171,7 @@
             int i, n;
 
             // Decrement checked indexes
-            i = Sequence.Search.binarySearch(checkedIndexes, index);
+            i = ArrayList.binarySearch(checkedIndexes, index);
             if (i < 0) {
                 i = -(i + 1);
             }
@@ -183,7 +183,7 @@
             }
 
             // Decrement disabled indexes
-            i = Sequence.Search.binarySearch(disabledIndexes, index);
+            i = ArrayList.binarySearch(disabledIndexes, index);
             if (i < 0) {
                 i = -(i + 1);
             }
@@ -958,7 +958,7 @@
      * @param index
      */
     public boolean isItemChecked(int index) {
-        return (Sequence.Search.binarySearch(checkedIndexes, index) >= 0);
+        return (ArrayList.binarySearch(checkedIndexes, index) >= 0);
     }
 
     /**
@@ -972,7 +972,7 @@
             throw new IllegalStateException("Checkmarks are not enabled.");
         }
 
-        int i = Sequence.Search.binarySearch(checkedIndexes, index);
+        int i = ArrayList.binarySearch(checkedIndexes, index);
 
         if ((i < 0 && checked)
             || (i >= 0 && !checked)) {
@@ -1010,7 +1010,7 @@
      * otherwise.
      */
     public boolean isItemDisabled(int index) {
-        return (Sequence.Search.binarySearch(disabledIndexes, index) >= 0);
+        return (ArrayList.binarySearch(disabledIndexes, index) >= 0);
     }
 
     /**
@@ -1023,7 +1023,7 @@
      * <tt>true</tt> to disable the item; <tt>false</tt>, otherwise.
      */
     public void setItemDisabled(int index, boolean disabled) {
-        int i = Sequence.Search.binarySearch(disabledIndexes, index);
+        int i = ArrayList.binarySearch(disabledIndexes, index);
 
         if ((i < 0 && disabled)
             || (i >= 0 && !disabled)) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/SpanSequence.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/SpanSequence.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/SpanSequence.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/SpanSequence.java Sun May 31 22:17:38 2009
@@ -276,7 +276,7 @@
      * of the span as defined by the binary search algorithm.
      */
     public int indexOf(Span span) {
-        return Search.binarySearch(spans, span, spanComparator);
+        return ArrayList.binarySearch(spans, span, spanComparator);
     }
 
     /**

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/TableView.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/TableView.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/TableView.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/TableView.java Sun May 31 22:17:38 2009
@@ -626,7 +626,7 @@
             selectedRanges.insertIndex(index);
 
             // Increment disabled indexes
-            int i = Sequence.Search.binarySearch(disabledIndexes, index);
+            int i = ArrayList.binarySearch(disabledIndexes, index);
             if (i < 0) {
                 i = -(i + 1);
             }
@@ -648,7 +648,7 @@
             selectedRanges.removeIndexes(index, count);
 
             // Decrement disabled indexes
-            int i = Sequence.Search.binarySearch(disabledIndexes, index);
+            int i = ArrayList.binarySearch(disabledIndexes, index);
             if (i < 0) {
                 i = -(i + 1);
             }
@@ -1359,7 +1359,7 @@
      * otherwise.
      */
     public boolean isRowDisabled(int index) {
-        return (Sequence.Search.binarySearch(disabledIndexes, index) >= 0);
+        return (ArrayList.binarySearch(disabledIndexes, index) >= 0);
     }
 
     /**
@@ -1372,7 +1372,7 @@
      * <tt>true</tt> to disable the row; <tt>false</tt>, otherwise.
      */
     public void setRowDisabled(int index, boolean disabled) {
-        int i = Sequence.Search.binarySearch(disabledIndexes, index);
+        int i = ArrayList.binarySearch(disabledIndexes, index);
 
         if ((i < 0 && disabled)
             || (i >= 0 && !disabled)) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/TreeView.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/TreeView.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/TreeView.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/TreeView.java Sun May 31 22:17:38 2009
@@ -571,13 +571,13 @@
          * @param index
          * The index of the inserted item within its parent.
          */
-        private void incrementPaths(Sequence<Path> paths, Path basePath, int index) {
+        private void incrementPaths(ArrayList<Path> paths, Path basePath, int index) {
             // Calculate the child's path
             Path childPath = new Path(basePath);
             childPath.add(index);
 
             // Find the child path's place in our sorted paths sequence
-            int i = Sequence.Search.binarySearch(paths, childPath, PATH_COMPARATOR);
+            int i = ArrayList.binarySearch(paths, childPath, PATH_COMPARATOR);
             if (i < 0) {
                 i = -(i + 1);
             }
@@ -615,14 +615,14 @@
          * @param count
          * The number of items removed.
          */
-        private void clearAndDecrementPaths(Sequence<Path> paths, Path basePath, int index, int count) {
+        private void clearAndDecrementPaths(ArrayList<Path> paths, Path basePath, int index, int count) {
             int depth = basePath.getLength();
 
             // Find the index of the first path to clear (inclusive)
             Path testPath = new Path(basePath);
             testPath.add(index);
 
-            int start = Sequence.Search.binarySearch(paths, testPath, PATH_COMPARATOR);
+            int start = ArrayList.binarySearch(paths, testPath, PATH_COMPARATOR);
             if (start < 0) {
                 start = -(start + 1);
             }
@@ -630,7 +630,7 @@
             // Find the index of the last path to clear (exclusive)
             testPath.update(depth, index + count);
 
-            int end = Sequence.Search.binarySearch(paths, testPath, PATH_COMPARATOR);
+            int end = ArrayList.binarySearch(paths, testPath, PATH_COMPARATOR);
             if (end < 0) {
                 end = -(end + 1);
             }
@@ -670,13 +670,13 @@
          * @param index
          * The index of the updated item within its parent.
          */
-        private void clearPaths(Sequence<Path> paths, Path basePath, int index) {
+        private void clearPaths(ArrayList<Path> paths, Path basePath, int index) {
             // Calculate the child's path
             Path childPath = new Path(basePath);
             childPath.add(index);
 
             // Find the child path's place in our sorted paths sequence
-            int clearIndex = Sequence.Search.binarySearch(paths, childPath, PATH_COMPARATOR);
+            int clearIndex = ArrayList.binarySearch(paths, childPath, PATH_COMPARATOR);
             if (clearIndex < 0) {
                 clearIndex = -(clearIndex + 1);
             }
@@ -706,9 +706,9 @@
          * @param basePath
          * The path whose children were sorted.
          */
-        private void clearPaths(Sequence<Path> paths, Path basePath) {
+        private void clearPaths(ArrayList<Path> paths, Path basePath) {
             // Find first descendant in paths list, if it exists
-            int index = Sequence.Search.binarySearch(paths, basePath, PATH_COMPARATOR);
+            int index = ArrayList.binarySearch(paths, basePath, PATH_COMPARATOR);
             index = (index < 0 ? -(index + 1) : index + 1);
 
             // Remove all descendants from the paths list
@@ -1413,7 +1413,7 @@
         NodeCheckState checkState = NodeCheckState.UNCHECKED;
 
         if (checkmarksEnabled) {
-            int index = Sequence.Search.binarySearch(checkedPaths, path, PATH_COMPARATOR);
+            int index = ArrayList.binarySearch(checkedPaths, path, PATH_COMPARATOR);
 
             if (index >= 0) {
                 checkState = NodeCheckState.CHECKED;

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/TextAreaSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/TextAreaSkin.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/TextAreaSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/TextAreaSkin.java Sun May 31 22:17:38 2009
@@ -468,7 +468,7 @@
             // Get the index of the node view at x, y
             nullNodeView.setLocation(x, y);
 
-            int i = Sequence.Search.binarySearch(nodeViews, nullNodeView,
+            int i = ArrayList.binarySearch(nodeViews, nullNodeView,
                 nodeViewLocationComparator);
 
             if (i < 0) {
@@ -507,7 +507,7 @@
             // Get the index of the node view at offset
             nullNodeView.setOffset(offset);
 
-            int i = Sequence.Search.binarySearch(nodeViews, nullNodeView,
+            int i = ArrayList.binarySearch(nodeViews, nullNodeView,
                 nodeViewOffsetComparator);
 
             if (i < 0) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/text/Element.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/text/Element.java?rev=780520&r1=780519&r2=780520&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/text/Element.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/text/Element.java Sun May 31 22:17:38 2009
@@ -451,7 +451,7 @@
 
         int index = -1;
         if (node.getParent() == this) {
-            index = Sequence.Search.binarySearch(nodes, node, nodeOffsetComparator);
+            index = ArrayList.binarySearch(nodes, node, nodeOffsetComparator);
 
             if (index < 0) {
                 // Decrement the index by one, since we only get exact