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

svn commit: r758461 [5/47] - in /incubator/pivot/branches: ./ 1.1/ 1.1/charts-test/ 1.1/charts-test/src/ 1.1/charts-test/src/pivot/ 1.1/charts-test/src/pivot/charts/ 1.1/charts-test/src/pivot/charts/test/ 1.1/charts/ 1.1/charts/lib/ 1.1/charts/src/ 1.1...

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/Sequence.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/Sequence.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/Sequence.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/Sequence.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections;
+
+import java.util.Comparator;
+
+/**
+ * Interface representing an ordered sequence of items.
+ *
+ * @author gbrown
+ */
+public interface Sequence<T> {
+    /**
+     * Collection of static utility methods providing path access to nested
+     * sequence data.
+     *
+     * @author gbrown
+     */
+    public static class Tree {
+        /**
+         * Adds an item to a nested sequence.
+         *
+         * @param sequence
+         * The root sequence.
+         *
+         * @param item
+         * The item to be added to the sequence.
+         *
+         * @param path
+         * The path of the sequence to which the item should be added.
+         *
+         * @return
+         * The index at which the item was inserted, relative to the parent
+         * sequence.
+         */
+        @SuppressWarnings("unchecked")
+        public static <T> int add(Sequence<T> sequence, T item, Sequence<Integer> path) {
+            return ((Sequence<T>)get(sequence, path)).add(item);
+        }
+
+        /**
+         * Inserts an item into a nested sequence.
+         *
+         * @param sequence
+         * The root sequence.
+         *
+         * @param item
+         * The item to be inserted into the sequence.
+         *
+         * @param path
+         * The path of the sequence into which the item should be inserted.
+         *
+         * @param index
+         * The index at which the item should be inserted within the parent
+         * sequence.
+         */
+        @SuppressWarnings("unchecked")
+        public static <T> void insert(Sequence<T> sequence, T item, Sequence<Integer> path,
+            int index) {
+            ((Sequence<T>)get(sequence, path)).insert(item, index);
+        }
+
+        /**
+         * Updates an item in a nested sequence.
+         *
+         * @param sequence
+         * The root sequence.
+         *
+         * @param path
+         * The path of the item to update.
+         *
+         * @param item
+         * The item that will replace any existing value at the given path.
+         *
+         * @return
+         * The item that was previously stored at the given path.
+         */
+        @SuppressWarnings("unchecked")
+        public static <T> T update(Sequence<T> sequence, Sequence<Integer> path, T item) {
+            if (sequence == null) {
+                throw new IllegalArgumentException("sequence is null.");
+            }
+
+            if (path == null) {
+                throw new IllegalArgumentException("path is null.");
+            }
+
+            int i = 0, n = path.getLength() - 1;
+            while (i < n) {
+                sequence = (Sequence<T>)sequence.get(path.get(i++));
+            }
+
+            return sequence.update(path.get(i), item);
+        }
+
+        /**
+         * Removes the first occurrence of an item from a nested sequence.
+         *
+         * @param sequence
+         * The root sequence.
+         *
+         * @param item
+         * The item to remove.
+         *
+         * @return
+         * The path of the item that was removed.
+         */
+        public static <T> Sequence<Integer> remove(Sequence<T> sequence, T item) {
+            Sequence<Integer> path = pathOf(sequence, item);
+            if (path == null) {
+                throw new IllegalArgumentException("item is not a descendant of sequence.");
+            }
+
+            remove(sequence, path, 1);
+
+            return path;
+        }
+
+        /**
+         * Removes an item from a nested sequence.
+         *
+         * @param sequence
+         * The root sequence.
+         *
+         * @param path
+         * The path of the item to remove.
+         */
+        @SuppressWarnings("unchecked")
+        public static <T> Sequence<T> remove(Sequence<T> sequence, Sequence<Integer> path, int count) {
+            if (sequence == null) {
+                throw new IllegalArgumentException("sequence is null.");
+            }
+
+            if (path == null) {
+                throw new IllegalArgumentException("path is null.");
+            }
+
+            int i = 0, n = path.getLength() - 1;
+            while (i < n) {
+                sequence = (Sequence<T>)sequence.get(path.get(i++));
+            }
+
+            return sequence.remove(path.get(i), count);
+        }
+
+        /**
+         * Retrieves an item from a nested sequence.
+         *
+         * @param sequence
+         * The root sequence.
+         *
+         * @param path
+         * The path of the item to retrieve.
+         *
+         * @return
+         * The item at the given path, or <tt>null</tt> if the path is empty.
+         */
+        @SuppressWarnings("unchecked")
+        public static <T> T get(Sequence<T> sequence, Sequence<Integer> path) {
+            if (sequence == null) {
+                throw new IllegalArgumentException("sequence is null.");
+            }
+
+            if (path == null) {
+                throw new IllegalArgumentException("path is null.");
+            }
+
+            int i = 0, n = path.getLength() - 1;
+            while (i < n) {
+                sequence = (Sequence<T>)sequence.get(path.get(i++));
+            }
+
+            return sequence.get(path.get(i));
+        }
+
+        /**
+         * Returns the path to an item in a nested sequence.
+         *
+         * @param sequence
+         * The root sequence.
+         *
+         * @param item
+         * The item to locate.
+         *
+         * @return
+         * The path of first occurrence of the item if it exists in the
+         * sequence; <tt>null</tt>, otherwise.
+         */
+        @SuppressWarnings("unchecked")
+        public static <T> Sequence<Integer> pathOf(Sequence<T> sequence, T item) {
+            if (sequence == null) {
+                throw new IllegalArgumentException("sequence is null.");
+            }
+
+            if (item == null) {
+                throw new IllegalArgumentException("item is null.");
+            }
+
+            Sequence<Integer> path = null;
+
+            for (int i = 0, n = sequence.getLength(); i < n && path == null; i++) {
+                T t = sequence.get(i);
+
+                if (t.equals(item)) {
+                    path = new ArrayList<Integer>();
+                    path.add(i);
+                } else {
+                    if (t instanceof Sequence) {
+                        path = pathOf((Sequence<T>)t, item);
+
+                        if (path != null) {
+                            path.insert(0, i);
+                        }
+                    }
+                }
+            }
+
+            return path;
+        }
+
+        /**
+         * Determines whether the path represented by the second argument is
+         * a descendant of the path represented by the first argument.
+         *
+         * @param ancestorPath
+         * The ancestor path to test.
+         *
+         * @param descendantPath
+         * The descendant path to test.
+         */
+        public static boolean isDescendant(Sequence<Integer> ancestorPath,
+            Sequence<Integer> descendantPath) {
+            int ancestorLength = ancestorPath.getLength();
+            int descendantLength = descendantPath.getLength();
+
+            boolean result = (ancestorLength <= descendantLength);
+
+            if (result) {
+                for (int i = 0, n = ancestorLength; i < n; i++) {
+                    int index1 = ancestorPath.get(i);
+                    int index2 = descendantPath.get(i);
+
+                    if (index1 != index2) {
+                        result = false;
+                        break;
+                    }
+                }
+            }
+
+            return result;
+        }
+    }
+
+    /**
+     * 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
+     * The item to be added to the sequence.
+     *
+     * @return
+     * The index at which the item was added.
+     */
+    public int add(T item);
+
+    /**
+     * Inserts an item into the sequence at a specific index.
+     *
+     * @param item
+     * The item to be added to the sequence.
+     *
+     * @param index
+     * The index at which the item should be inserted. Must be a value between
+     * <tt>0</tt> and <tt>getLength()</tt>.
+     */
+    public void insert(T item, int index);
+
+    /**
+     * Updates the item at the given index.
+     *
+     * @param index
+     * The index of the item to update.
+     *
+     * @param item
+     * The item that will replace any existing value at the given index.
+     *
+     * @return
+     * The item that was previously stored at the given index.
+     */
+    public T update(int index, T item);
+
+    /**
+     * Removes the first occurrence of the given item from the sequence.
+     *
+     * @param item
+     * The item to remove.
+     *
+     * @return
+     * The index of the item that was removed, or <tt>-1</tt> if the item
+     * could not be found.
+     *
+     * @see #remove(int, int)
+     */
+    public int remove(T item);
+
+    /**
+     * Removes one or more items from the sequence.
+     *
+     * @param index
+     * The starting index to remove.
+     *
+     * @param count
+     * The number of items to remove, beginning with <tt>index</tt>.
+     *
+     * @return
+     * A sequence containing the items that were removed.
+     */
+    public Sequence<T> remove(int index, int count);
+
+    /**
+     * Retrieves the item at the given index.
+     *
+     * @param index
+     * The index of the item to retrieve.
+     */
+    public T get(int index);
+
+    /**
+     * Returns the index of an item in the sequence.
+     *
+     * @param item
+     * The item to locate.
+     *
+     * @return
+     * The index of first occurrence of the item if it exists in the sequence;
+     * <tt>-1</tt>, otherwise.
+     */
+    public int indexOf(T item);
+
+    /**
+     * Returns the length of the sequence.
+     *
+     * @return
+     * The number of items in the sequence.
+     */
+    public int getLength();
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/Set.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/Set.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/Set.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/Set.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections;
+
+import java.util.Comparator;
+import pivot.util.ListenerList;
+
+/**
+ * Collection interface representing a group of unique elements.
+ *
+ * @author gbrown
+ */
+public interface Set<E> extends Group<E>, Collection<E> {
+    /**
+     * Set listener list implementation.
+     *
+     * @author gbrown
+     */
+    public static class SetListenerList<E>
+        extends ListenerList<SetListener<E>> implements SetListener<E> {
+        public void elementAdded(Set<E> set, E element) {
+            for (SetListener<E> listener : this) {
+                listener.elementAdded(set, element);
+            }
+        }
+
+        public void elementRemoved(Set<E> set, E element) {
+            for (SetListener<E> listener : this) {
+                listener.elementRemoved(set, element);
+            }
+        }
+
+        public void setCleared(Set<E> set) {
+            for (SetListener<E> listener : this) {
+                listener.setCleared(set);
+            }
+        }
+
+        public void comparatorChanged(Set<E> set, Comparator<E> previousComparator) {
+            for (SetListener<E> listener : this) {
+                listener.comparatorChanged(set, previousComparator);
+            }
+        }
+    }
+
+    /**
+     * @see SetListener#elementAdded(Set, Object)
+     */
+    public void add(E element);
+
+    /**
+     * @see SetListener#elementRemoved(Set, Object)
+     */
+    public void remove(E element);
+
+    /**
+     * @see SetListener#setCleared(Set)
+     */
+    public void clear();
+
+    /**
+     * @see SetListener#setCleared(Set)
+     */
+    public void setComparator(Comparator<E> comparator);
+
+    /**
+     * Returns the set listener collection.
+     */
+    public ListenerList<SetListener<E>> getSetListeners();
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/SetListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/SetListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/SetListener.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/SetListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections;
+
+import java.util.Comparator;
+
+/**
+ * Set listener interface.
+ *
+ * @author gbrown
+ */
+public interface SetListener<E> {
+    /**
+     * Called when an element is added to a set.
+     *
+     * @param set
+     * The source of the set event.
+     *
+     * @param element
+     * The element that was added to the set.
+     */
+    public void elementAdded(Set<E> set, E element);
+
+    /**
+     * Called when an element is removed from the set.
+     *
+     * @param set
+     * The source of the set event.
+     *
+     * @param element
+     * The element that was removed from the set.
+     */
+    public void elementRemoved(Set<E> set, E element);
+
+    /**
+     * Called when set data has been reset.
+     *
+     * @param set
+     * The source of the set event.
+     */
+    public void setCleared(Set<E> set);
+
+    /**
+     * Called when a set's comparator has changed.
+     *
+     * @param set
+     * The source of the event.
+     *
+     * @param previousComparator
+     * The previous comparator value.
+     */
+    public void comparatorChanged(Set<E> set, Comparator<E> previousComparator);
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/Stack.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/Stack.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/Stack.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/Stack.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections;
+
+/**
+ * Interface representing a last-in, first-out (LIFO) stack when unsorted, and
+ * a priority stack when sorted.
+ *
+ * @author gbrown
+ */
+public interface Stack<T> extends List<T> {
+    /**
+     * "Pushes" an item onto the stack. If the stack is unsorted, the item is
+     * added at the top of the stack (<tt>getLength()</tt>). Otherwise, it is
+     * inserted at the appropriate index.
+     *
+     * @param item
+     * The item to push onto the stack.
+     */
+    public void push(T item);
+
+    /**
+     * Removes the top item from the stack and returns it.
+     *
+     * @throws IllegalStateException
+     * If the stack contains no items.
+     */
+    public T pop();
+
+    /**
+     * Returns the item on top of the stack without removing it from the stack.
+     * Returns null if the stack contains no items. Will also return null if the
+     * top item in the stack is null. <tt>getLength()</tt> can be used to
+     * distinguish between these two cases.
+     */
+    public T peek();
+
+    /**
+     * Replaces the item on top of the stack.
+     *
+     * @throws IllegalStateException
+     * If the stack contains no items.
+     */
+    public T poke(T item);
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/ListAdapter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/ListAdapter.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/ListAdapter.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/ListAdapter.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.adapter;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import pivot.collections.List;
+import pivot.collections.ListListener;
+import pivot.collections.Sequence;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+
+/**
+ * Implementation of the {@link List} interface that is backed by an
+ * instance of <tt>java.util.List</tt>.
+ */
+public class ListAdapter<T> implements List<T> {
+    private java.util.List<T> list = null;
+    private Comparator<T> comparator = null;
+
+    private ListListenerList<T> listListeners = new ListListenerList<T>();
+
+    public ListAdapter(java.util.List<T> list) {
+        if (list == null) {
+            throw new IllegalArgumentException("list is null.");
+        }
+
+        this.list = list;
+    }
+
+    public java.util.List<T> getList() {
+        return list;
+    }
+
+    public int add(T item) {
+        int index = -1;
+
+        if (comparator == null) {
+            index = getLength();
+        }
+        else {
+            // Perform a binary search to find the insertion point
+            index = Search.binarySearch(this, item, comparator);
+            if (index < 0) {
+                index = -(index + 1);
+            }
+        }
+
+        list.add(index, item);
+        listListeners.itemInserted(this, index);
+
+        return index;
+    }
+
+    public void insert(T item, int index) {
+        if (comparator != null
+            && Search.binarySearch(this, item, comparator) != -(index + 1)) {
+            throw new IllegalArgumentException("Illegal insertion point.");
+        }
+
+        list.add(index, item);
+
+        listListeners.itemInserted(this, index);
+    }
+
+    public T update(int index, T item) {
+        if (comparator != null
+            && Search.binarySearch(this, item, comparator) != index) {
+            throw new IllegalArgumentException("Illegal item modification.");
+        }
+
+        T previousItem = list.get(index);
+        list.set(index, item);
+        listListeners.itemUpdated(this, index, previousItem);
+
+        return previousItem;
+    }
+
+    public int remove(T item) {
+        int index = indexOf(item);
+
+        if (index == -1) {
+            throw new IllegalArgumentException("item is not an element of this list.");
+        }
+
+        remove(index, 1);
+
+        return index;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Sequence<T> remove(int index, int count) {
+        java.util.List<T> removedList = null;
+        try {
+            removedList = (java.util.List<T>)list.getClass().newInstance();
+        } catch(IllegalAccessException exception) {
+        } catch(InstantiationException exception) {
+        }
+
+        for (int i = count - 1; i >= 0; i--) {
+            removedList.add(0, list.remove(index + i));
+        }
+
+        // Fire event
+        List<T> removed = new ListAdapter<T>(removedList);
+        listListeners.itemsRemoved(this, index, removed);
+
+        return removed;
+    }
+
+    public void clear() {
+        list.clear();
+        listListeners.itemsRemoved(this, 0, null);
+    }
+
+    public T get(int index) {
+        return list.get(index);
+    }
+
+    public int indexOf(T item) {
+        return list.indexOf(item);
+    }
+
+    public int getLength() {
+        return list.size();
+    }
+
+    public Comparator<T> getComparator() {
+        return comparator;
+    }
+
+    public void setComparator(Comparator<T> comparator) {
+        Comparator<T> previousComparator = this.comparator;
+
+        if (previousComparator != comparator) {
+            if (comparator != null) {
+            	Collections.sort(list, comparator);
+            }
+
+            this.comparator = comparator;
+
+            listListeners.comparatorChanged(this, previousComparator);
+        }
+    }
+
+    public Iterator<T> iterator() {
+        return new ImmutableIterator<T>(list.iterator());
+    }
+
+    public ListenerList<ListListener<T>> getListListeners() {
+        return listListeners;
+    }
+
+    public String toString() {
+        return list.toString();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/MapAdapter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/MapAdapter.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/MapAdapter.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/MapAdapter.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.adapter;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.collections.Map;
+import pivot.collections.MapListener;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+
+/**
+ * Implementation of the {@link Map} interface that is backed by an
+ * instance of <tt>java.util.Map</tt>.
+ */
+public class MapAdapter<K, V> implements Map<K, V> {
+    private java.util.Map<K, V> map = null;
+    private MapListenerList<K, V> mapListeners = new MapListenerList<K, V>();
+
+    public MapAdapter(java.util.Map<K, V> map) {
+        if (map == null) {
+            throw new IllegalArgumentException("map is null.");
+        }
+
+        this.map = map;
+    }
+
+    public java.util.Map<K, V> getMap() {
+        return map;
+    }
+
+    public V get(K key) {
+        return map.get(key);
+    }
+
+    public V put(K key, V value) {
+        boolean update = map.containsKey(key);
+        V previousValue = map.put(key, value);
+
+        if (update) {
+            mapListeners.valueUpdated(this, key, previousValue);
+        }
+        else {
+            mapListeners.valueAdded(this, key);
+        }
+
+        return previousValue;
+    }
+
+    public V remove(K key) {
+        V value = null;
+
+        if (map.containsKey(key)) {
+            value = map.remove(key);
+            mapListeners.valueRemoved(this, key, value);
+        }
+
+        return value;
+    }
+
+    public void clear() {
+        map.clear();
+        mapListeners.mapCleared(this);
+    }
+
+    public boolean containsKey(K key) {
+        return map.containsKey(key);
+    }
+
+
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    public Comparator<K> getComparator() {
+        return null;
+    }
+
+    public void setComparator(Comparator<K> comparator) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator<K> iterator() {
+        return new ImmutableIterator<K>(map.keySet().iterator());
+    }
+
+    public ListenerList<MapListener<K, V>> getMapListeners() {
+        return mapListeners;
+    }
+
+    public String toString() {
+        return map.toString();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/SetAdapter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/SetAdapter.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/SetAdapter.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/SetAdapter.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.adapter;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.collections.Set;
+import pivot.collections.SetListener;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+
+/**
+ * Implementation of the {@link Set} interface that is backed by an
+ * instance of <tt>java.util.Set</tt>.
+ */
+public class SetAdapter<E> implements Set<E> {
+    private java.util.Set<E> set = null;
+    private SetListenerList<E> setListeners = new SetListenerList<E>();
+
+    public SetAdapter(java.util.Set<E> set) {
+        if (set == null) {
+            throw new IllegalArgumentException("set is null.");
+        }
+
+        this.set = set;
+    }
+
+    public java.util.Set<E> getSet() {
+        return set;
+    }
+
+    public void add(E element) {
+        if (!set.contains(element)) {
+            set.add(element);
+            setListeners.elementAdded(this, element);
+        }
+    }
+
+    public void remove(E element) {
+        if (set.contains(element)) {
+            set.remove(element);
+            setListeners.elementRemoved(this, element);
+        }
+    }
+
+    public void clear() {
+        set.clear();
+        setListeners.setCleared(this);
+    }
+
+    public boolean contains(E element) {
+        return set.contains(element);
+    }
+
+    public boolean isEmpty() {
+        return set.isEmpty();
+    }
+
+    public Comparator<E> getComparator() {
+        return null;
+    }
+
+    public void setComparator(Comparator<E> comparator) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator<E> iterator() {
+        return new ImmutableIterator<E>(set.iterator());
+    }
+
+    public ListenerList<SetListener<E>> getSetListeners() {
+        return setListeners;
+    }
+
+    public String toString() {
+        return set.toString();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/package.html
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/package.html?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/package.html (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/adapter/package.html Wed Mar 25 23:08:38 2009
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>Provides a set of collection implementations that are backed by java.util collections.</p>
+</body>
+</html>

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedCollection.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedCollection.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedCollection.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedCollection.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.concurrent;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.collections.Collection;
+import pivot.util.ImmutableIterator;
+
+/**
+ * Abstract base class for synchronized collection wrappers.
+ * <p>
+ * NOTE In order to guarantee thread-safe access, all access to the backing
+ * collection must be via the synchronized wrapper.
+ *
+ * @author gbrown
+ */
+public abstract class SynchronizedCollection<T> implements Collection<T> {
+    protected Collection<T> collection = null;
+
+    public SynchronizedCollection(Collection<T> collection) {
+        if (collection == null) {
+            throw new IllegalArgumentException("collection is null.");
+        }
+
+        this.collection = collection;
+    }
+
+    public synchronized Comparator<T> getComparator() {
+        return collection.getComparator();
+    }
+
+    public synchronized void setComparator(Comparator<T> comparator) {
+        collection.setComparator(comparator);
+    }
+
+    /**
+     * NOTE Callers must manually synchronize on the SynchronizedCollection
+     * instance to ensure thread safety during iteration.
+     */
+    public Iterator<T> iterator() {
+        return new ImmutableIterator<T>(collection.iterator());
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedList.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedList.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedList.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.concurrent;
+
+import java.util.Comparator;
+import pivot.collections.List;
+import pivot.collections.ListListener;
+import pivot.collections.Sequence;
+import pivot.util.ListenerList;
+import pivot.util.concurrent.SynchronizedListenerList;
+
+/**
+ * Synchronized implementation of the {@link List} interface.
+ *
+ * @author gbrown
+ */
+public class SynchronizedList<T> extends SynchronizedCollection<T>
+    implements List<T> {
+    /**
+     * Synchronized list listener list implementation. Proxies events fired
+     * by inner list to listeners of synchronized list.
+     *
+     * @author gbrown
+     */
+    private class SynchronizedListListenerList
+        extends SynchronizedListenerList<ListListener<T>>
+        implements ListListener<T> {
+        public synchronized void itemInserted(List<T> list, int index) {
+            for (ListListener<T> listener : this) {
+                listener.itemInserted(SynchronizedList.this, index);
+            }
+        }
+
+        public synchronized void itemsRemoved(List<T> list, int index, Sequence<T> items) {
+            for (ListListener<T> listener : this) {
+                listener.itemsRemoved(SynchronizedList.this, index, items);
+            }
+        }
+
+        public synchronized void itemUpdated(List<T> list, int index, T previousItem) {
+            for (ListListener<T> listener : this) {
+                listener.itemUpdated(SynchronizedList.this, index, previousItem);
+            }
+        }
+
+        public synchronized void comparatorChanged(List<T> list, Comparator<T> previousComparator) {
+            for (ListListener<T> listener : this) {
+                listener.comparatorChanged(SynchronizedList.this, previousComparator);
+            }
+        }
+    }
+
+    private SynchronizedListListenerList listListeners = new SynchronizedListListenerList();
+
+    public SynchronizedList(List<T> list) {
+        super(list);
+
+        list.getListListeners().add(listListeners);
+    }
+
+    public synchronized int add(T item) {
+        return ((List<T>)collection).add(item);
+    }
+
+    public synchronized void insert(T item, int index) {
+        ((List<T>)collection).insert(item, index);
+    }
+
+    public synchronized T update(int index, T item) {
+        return ((List<T>)collection).update(index, item);
+    }
+
+    public int remove (T item) {
+        return ((List<T>)collection).remove(item);
+    }
+
+    public synchronized Sequence<T> remove(int index, int count) {
+        return ((List<T>)collection).remove(index, count);
+    }
+
+    public synchronized void clear() {
+        ((List<T>)collection).clear();
+    }
+
+    public synchronized T get(int index) {
+        return ((List<T>)collection).get(index);
+    }
+
+    public synchronized int indexOf(T item) {
+        return ((List<T>)collection).indexOf(item);
+    }
+
+    public synchronized int getLength() {
+        return ((List<T>)collection).getLength();
+    }
+
+    public ListenerList<ListListener<T>> getListListeners() {
+        return listListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedMap.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedMap.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedMap.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedMap.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.concurrent;
+
+import java.util.Comparator;
+
+import pivot.collections.Map;
+import pivot.collections.MapListener;
+import pivot.util.ListenerList;
+import pivot.util.concurrent.SynchronizedListenerList;
+
+/**
+ * Synchronized implementation of the {@link Map} interface.
+ *
+ * @author gbrown
+ */
+public class SynchronizedMap<K, V> extends SynchronizedCollection<K>
+    implements Map<K, V> {
+    /**
+     * Synchronized map listener list implementation. Proxies events fired
+     * by inner map to listeners of synchronized map.
+     *
+     * @author gbrown
+     */
+    private class SynchronizedMapListenerList
+        extends SynchronizedListenerList<MapListener<K, V>>
+        implements MapListener<K, V> {
+        public synchronized void valueAdded(Map<K, V> map, K key) {
+            for (MapListener<K, V> listener : this) {
+                listener.valueAdded(SynchronizedMap.this, key);
+            }
+        }
+
+        public synchronized void valueRemoved(Map<K, V> map, K key, V value) {
+            for (MapListener<K, V> listener : this) {
+                listener.valueRemoved(SynchronizedMap.this, key, value);
+            }
+        }
+
+        public synchronized void valueUpdated(Map<K, V> map, K key, V previousValue) {
+            for (MapListener<K, V> listener : this) {
+                listener.valueUpdated(SynchronizedMap.this, key, previousValue);
+            }
+        }
+
+        public synchronized void mapCleared(Map<K, V> map) {
+            for (MapListener<K, V> listener : this) {
+                listener.mapCleared(SynchronizedMap.this);
+            }
+        }
+
+        public synchronized void comparatorChanged(Map<K, V> map, Comparator<K> previousComparator) {
+            for (MapListener<K, V> listener : this) {
+                listener.comparatorChanged(SynchronizedMap.this, previousComparator);
+            }
+        }
+    }
+
+    private SynchronizedMapListenerList mapListeners = new SynchronizedMapListenerList();
+
+    public SynchronizedMap(Map<K, V> map) {
+        super(map);
+
+        map.getMapListeners().add(mapListeners);
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized V get(K key) {
+        return ((Map<K, V>)collection).get(key);
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized V put(K key, V value) {
+        return ((Map<K, V>)collection).put(key, value);
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized V remove(K key) {
+        return ((Map<K, V>)collection).remove(key);
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized void clear() {
+        ((Map<K, V>)collection).clear();
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized boolean isEmpty() {
+        return ((Map<K, V>)collection).isEmpty();
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized boolean containsKey(K key) {
+        return ((Map<K, V>)collection).containsKey(key);
+    }
+
+    public ListenerList<MapListener<K, V>> getMapListeners() {
+        return mapListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedQueue.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedQueue.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedQueue.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedQueue.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.concurrent;
+
+import pivot.collections.Queue;
+
+/**
+ * Synchronized implementation of the {@link Queue} interface.
+ *
+ * @author gbrown
+ */
+public class SynchronizedQueue<T> extends SynchronizedList<T>
+    implements Queue<T> {
+    public SynchronizedQueue(Queue<T> queue) {
+        super(queue);
+    }
+
+    public synchronized void enqueue(T item) {
+        ((Queue<T>)collection).enqueue(item);
+
+        notify();
+    }
+
+    /**
+     * Removes an item from the head of the queue, blocking if the queue is
+     * empty.
+     *
+     * @return
+     * The item at the head of the queue, or null if the removing thread
+     * was interrupted.
+     */
+    public synchronized T dequeue() {
+        T item = null;
+
+        try {
+            while (getLength() == 0) {
+                wait();
+            }
+
+            item = ((Queue<T>)collection).dequeue();
+        } catch(InterruptedException exception) {
+        }
+
+        return item;
+    }
+
+    public synchronized T peek() {
+        return ((Queue<T>)collection).peek();
+    }
+
+    @Override
+    public synchronized int add(T item) {
+        int index = super.add(item);
+
+        notify();
+
+        return index;
+    }
+
+    @Override
+    public synchronized void insert(T item, int index) {
+        super.insert(item, index);
+
+        notify();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedSet.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedSet.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedSet.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedSet.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.concurrent;
+
+import java.util.Comparator;
+
+import pivot.collections.Set;
+import pivot.collections.SetListener;
+import pivot.util.ListenerList;
+import pivot.util.concurrent.SynchronizedListenerList;
+
+/**
+ * Synchronized implementation of the {@link Set} interface.
+ *
+ * @author gbrown
+ */
+public class SynchronizedSet<E> extends SynchronizedCollection<E>
+    implements Set<E> {
+    /**
+     * Synchronized set listener list implementation. Proxies events fired
+     * by inner set to listeners of synchronized set.
+     *
+     * @author gbrown
+     */
+    private class SynchronizedSetListenerList
+        extends SynchronizedListenerList<SetListener<E>>
+        implements SetListener<E> {
+        public void elementAdded(Set<E> set, E element) {
+            for (SetListener<E> listener : this) {
+                listener.elementAdded(set, element);
+            }
+        }
+
+        public void elementRemoved(Set<E> set, E element) {
+            for (SetListener<E> listener : this) {
+                listener.elementRemoved(SynchronizedSet.this, element);
+            }
+        }
+
+        public void setCleared(Set<E> set) {
+            for (SetListener<E> listener : this) {
+                listener.setCleared(SynchronizedSet.this);
+            }
+        }
+
+        public void comparatorChanged(Set<E> set, Comparator<E> previousComparator) {
+            for (SetListener<E> listener : this) {
+                listener.comparatorChanged(SynchronizedSet.this, previousComparator);
+            }
+        }
+    }
+
+    private SynchronizedSetListenerList setListeners = new SynchronizedSetListenerList();
+
+    public SynchronizedSet(Set<E> set) {
+        super(set);
+
+        set.getSetListeners().add(setListeners);
+    }
+
+    public synchronized void add(E element) {
+        ((Set<E>)collection).add(element);
+    }
+
+    public synchronized void remove(E element) {
+        ((Set<E>)collection).remove(element);
+    }
+
+    public synchronized void clear() {
+        ((Set<E>)collection).clear();
+    }
+
+    public synchronized boolean contains(E element) {
+        return ((Set<E>)collection).contains(element);
+    }
+
+    public synchronized boolean isEmpty() {
+        return ((Set<E>)collection).isEmpty();
+    }
+
+    public ListenerList<SetListener<E>> getSetListeners() {
+        return setListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedStack.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedStack.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedStack.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/SynchronizedStack.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.concurrent;
+
+import pivot.collections.Stack;
+
+/**
+ * Synchronized implementation of the {@link Stack} interface.
+ *
+ * @author gbrown
+ */
+public class SynchronizedStack<T> extends SynchronizedList<T>
+    implements Stack<T> {
+    public SynchronizedStack(Stack<T> stack) {
+        super(stack);
+    }
+
+    public void push(T item) {
+        ((Stack<T>)collection).push(item);
+    }
+
+    /**
+     * Removes an item from the top of the stack, blocking if the stack is
+     * currently empty.
+     *
+     * @return
+     * The item at the top of the stack, or null if the removing thread
+     * was interrupted.
+     */
+    public T pop() {
+        T item = null;
+
+        try {
+            while (getLength() == 0) {
+                wait();
+            }
+
+            item = ((Stack<T>)collection).pop();
+        }
+        catch(InterruptedException exception) {
+        }
+
+        return item;
+    }
+
+    public T peek() {
+        return ((Stack<T>)collection).peek();
+    }
+
+    public T poke(T item) {
+        return ((Stack<T>)collection).poke(item);
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/package.html
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/package.html?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/package.html (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/concurrent/package.html Wed Mar 25 23:08:38 2009
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>Contains a set of thread-safe collection implementations.</p>
+</body>
+</html>

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableList.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableList.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableList.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.immutable;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import pivot.collections.List;
+import pivot.collections.ListListener;
+import pivot.collections.Sequence;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+
+/**
+ * Unmodifiable implementation of the {@link List} interface.
+ *
+ * @author gbrown
+ */
+public final class ImmutableList<T> implements List<T> {
+    private List<T> list = null;
+
+    public ImmutableList(List<T> list) {
+        if (list == null) {
+            throw new IllegalArgumentException("list is null.");
+        }
+
+        this.list = list;
+    }
+
+    public int add(T item) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void insert(T item, int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    public T update(int index, T item) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int remove(T item) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Sequence<T> remove(int index, int count) {
+        throw new UnsupportedOperationException();    }
+
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    public T get(int index) {
+        return list.get(index);
+    }
+
+    public int indexOf(T item) {
+        return list.indexOf(item);
+    }
+
+    public int getLength() {
+        return list.getLength();
+    }
+
+    public Comparator<T> getComparator() {
+        return null;
+    }
+
+    public void setComparator(Comparator<T> comparator) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator<T> iterator() {
+        return new ImmutableIterator<T>(list.iterator());
+    }
+
+    public ListenerList<ListListener<T>> getListListeners() {
+        throw new UnsupportedOperationException();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableMap.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableMap.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableMap.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableMap.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.immutable;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.collections.Map;
+import pivot.collections.MapListener;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+
+/**
+ * Unmodifiable implementation of the {@link Map} interface.
+ *
+ * @author gbrown
+ */
+public class ImmutableMap<K, V> implements Map<K, V> {
+    private Map<K, V> map = null;
+
+    public ImmutableMap(Map<K, V> map) {
+        if (map == null) {
+            throw new IllegalArgumentException("map is null.");
+        }
+
+        this.map = map;
+    }
+
+    public V get(K key) {
+        return map.get(key);
+    }
+
+    public V put(K key, V value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public V remove(K key) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean containsKey(K key) {
+        return map.containsKey(key);
+    }
+
+
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    public Comparator<K> getComparator() {
+        return null;
+    }
+
+    public void setComparator(Comparator<K> comparator) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator<K> iterator() {
+        return new ImmutableIterator<K>(map.iterator());
+    }
+
+    public ListenerList<MapListener<K, V>> getMapListeners() {
+        throw new UnsupportedOperationException();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableSet.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableSet.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableSet.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/ImmutableSet.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.collections.immutable;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.collections.Set;
+import pivot.collections.SetListener;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+
+/**
+ * Unmodifiable implementation of the {@link Set} interface.
+ *
+ * @author gbrown
+ */
+public class ImmutableSet<E> implements Set<E> {
+    private Set<E> set = null;
+
+    public ImmutableSet(Set<E> set) {
+        if (set == null) {
+            throw new IllegalArgumentException("set is null.");
+        }
+
+        this.set = set;
+    }
+
+    public void add(E element) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void remove(E element) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean contains(E element) {
+        return set.contains(element);
+    }
+
+    public boolean isEmpty() {
+        return set.isEmpty();
+    }
+
+    public Comparator<E> getComparator() {
+        return null;
+    }
+
+    public void setComparator(Comparator<E> comparator) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator<E> iterator() {
+        return new ImmutableIterator<E>(set.iterator());
+    }
+
+    public ListenerList<SetListener<E>> getSetListeners() {
+        throw new UnsupportedOperationException();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/package.html
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/package.html?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/package.html (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/immutable/package.html Wed Mar 25 23:08:38 2009
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>Contains a set of read-only collection implementations.</p>
+</body>
+</html>

Added: incubator/pivot/branches/1.1/core/src/pivot/collections/package.html
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/collections/package.html?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/collections/package.html (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/collections/package.html Wed Mar 25 23:08:38 2009
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>Defines a set of classes and interfaces that serve as generic collections as well as the data model for UI components.</p>
+</body>
+</html>

Added: incubator/pivot/branches/1.1/core/src/pivot/io/FileList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/io/FileList.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/io/FileList.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/io/FileList.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009 VMware, 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.
+ */
+package pivot.io;
+
+import java.io.File;
+import java.util.Comparator;
+
+import pivot.collections.adapter.ListAdapter;
+
+/**
+ * Collection representing a list of files. Each entry in the list is unique;
+ * i.e. a single file can't be added to the list more than once.
+ *
+ * @author gbrown
+ */
+public class FileList extends ListAdapter<File> {
+    private static class FilePathComparator implements Comparator<File> {
+        public int compare(File file1, File file2) {
+            String path1 = file1.getPath();
+            String path2 = file2.getPath();
+
+            return path1.compareTo(path2);
+        }
+    }
+
+    private static final FilePathComparator filePathComparator = new FilePathComparator();
+
+    public FileList() {
+        this(new java.util.ArrayList<File>());
+    }
+
+    public FileList(java.util.List<File> files) {
+        super(files);
+
+        super.setComparator(filePathComparator);
+    }
+
+    @Override
+    public int add(File file) {
+        int index = indexOf(file);
+
+        if (index == -1) {
+            index = super.add(file);
+        }
+
+        return index;
+    }
+
+    public int add(Folder folder) {
+        for (File file : folder) {
+            if (file instanceof Folder) {
+                add((Folder)file);
+            } else {
+                add(file);
+            }
+        }
+
+        return -1;
+    }
+
+    @Override
+    public void insert(File file, int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File update(int index, File file) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setComparator(Comparator<File> comparator) {
+        throw new UnsupportedOperationException();
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/io/Folder.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/io/Folder.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/io/Folder.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/io/Folder.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2009 VMware, 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.
+ */
+package pivot.io;
+
+import java.io.File;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.collections.ArrayList;
+import pivot.collections.List;
+import pivot.collections.ListListener;
+import pivot.collections.Sequence;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+
+/**
+ * Class representing a folder in the file system.
+ *
+ * @author gbrown
+ */
+public class Folder extends File implements List<File> {
+    private static final long serialVersionUID = 0;
+
+    private ArrayList<File> files = null;
+
+    private Comparator<File> comparator = null;
+    private transient ListListenerList<File> listListeners = new ListListenerList<File>();
+
+    public Folder() {
+        super("");
+
+        refresh();
+    }
+
+    public Folder(String pathname) {
+        super(pathname);
+
+        if (!isDirectory()) {
+            throw new IllegalArgumentException(pathname + " is not a directory.");
+        }
+    }
+
+    public int add(File item) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void insert(File item, int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    public File update(int index, File item) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int remove(File item) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Sequence<File> remove(int index, int count) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    public File get(int index) {
+        if (files == null) {
+            refresh();
+        }
+
+        return files.get(index);
+    }
+
+    public int indexOf(File item) {
+        if (files == null) {
+            refresh();
+        }
+
+        int index = -1;
+        if (comparator == null) {
+            index = files.indexOf(item);
+        }
+        else {
+            // Perform a binary search to find the index
+            index = Search.binarySearch(this, item, comparator);
+            if (index < 0) {
+                index = -1;
+            }
+        }
+
+        return index;
+    }
+
+    public int getLength() {
+        if (files == null) {
+            refresh();
+        }
+
+        return files.getLength();
+    }
+
+    public void refresh() {
+        files = new ArrayList<File>();
+
+        File[] fileList;
+        if (getPath().length() == 0) {
+            fileList = listRoots();
+        } else {
+            fileList = listFiles();
+        }
+
+        if (fileList != null) {
+            for (int i = 0; i < fileList.length; i++) {
+                File file = fileList[i];
+
+                if (!file.isHidden()) {
+                    if (file.isDirectory()) {
+                        files.add(new Folder(file.getPath()));
+                    } else {
+                        files.add(file);
+                    }
+                }
+            }
+        }
+    }
+
+    public Comparator<File> getComparator() {
+        return comparator;
+    }
+
+    public void setComparator(Comparator<File> comparator) {
+        Comparator<File> previousComparator = this.comparator;
+
+        if (previousComparator != comparator) {
+            if (comparator != null
+                && files != null) {
+                Sequence.Sort.quickSort(files, comparator);
+            }
+
+            this.comparator = comparator;
+
+            listListeners.comparatorChanged(this, previousComparator);
+        }
+    }
+
+    public Iterator<File> iterator() {
+        if (files == null) {
+            refresh();
+        }
+
+        return new ImmutableIterator<File>(files.iterator());
+    }
+
+    public ListenerList<ListListener<File>> getListListeners() {
+        return listListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/io/IOTask.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/io/IOTask.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/io/IOTask.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/io/IOTask.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import pivot.util.concurrent.AbortException;
+import pivot.util.concurrent.Dispatcher;
+import pivot.util.concurrent.Task;
+
+/**
+ * Abstract base class for input/output tasks.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public abstract class IOTask<V> extends Task<V> {
+    /**
+     * Input stream that monitors the bytes that are read from it by
+     * incrementing the <tt>bytesReceived</tt> member variable.
+     *
+     * @author tvolkert
+     */
+    protected class MonitoredInputStream extends InputStream {
+        private InputStream inputStream;
+
+        long mark = 0;
+
+        public MonitoredInputStream(InputStream inputStream) {
+            this.inputStream = inputStream;
+        }
+
+        public int read() throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            int result = inputStream.read();
+
+            if (result != -1) {
+                bytesReceived++;
+            }
+
+            return result;
+        }
+
+        public int read(byte b[]) throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            int count = inputStream.read(b);
+
+            if (count != -1) {
+                bytesReceived += count;
+            }
+
+            return count;
+        }
+
+        public int read(byte b[], int off, int len) throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            int count = inputStream.read(b, off, len);
+
+            if (count != -1) {
+                bytesReceived += count;
+            }
+
+            return count;
+        }
+
+        public long skip(long n) throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            long count = inputStream.skip(n);
+            bytesReceived += count;
+            return count;
+        }
+
+        public int available() throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            return inputStream.available();
+        }
+
+        public void close() throws IOException {
+            inputStream.close();
+        }
+
+        public void mark(int readLimit) {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            inputStream.mark(readLimit);
+            mark = bytesReceived;
+        }
+
+        public void reset() throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            inputStream.reset();
+            bytesReceived = mark;
+        }
+
+        public boolean markSupported() {
+            return inputStream.markSupported();
+        }
+    }
+
+    /**
+     * Output stream that monitors the bytes that are written to it by
+     * incrementing the <tt>bytesSent</tt> member variable.
+     *
+     * @author tvolkert
+     */
+    protected class MonitoredOutputStream extends OutputStream {
+        private OutputStream outputStream;
+
+        public MonitoredOutputStream(OutputStream outputStream) {
+            this.outputStream = outputStream;
+        }
+
+        public void close() throws IOException {
+            outputStream.close();
+        }
+
+        public void flush() throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            outputStream.flush();
+        }
+
+        public void write(byte[] b) throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            outputStream.write(b);
+            bytesSent += b.length;
+        }
+
+        public void write(byte[] b, int off, int len) throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            outputStream.write(b, off, len);
+            bytesSent += len;
+        }
+
+        public void write(int b) throws IOException {
+            if (abort) {
+                throw new AbortException();
+            }
+
+            outputStream.write(b);
+            bytesSent++;
+        }
+    }
+
+    protected volatile long bytesSent = 0;
+    protected volatile long bytesReceived = 0;
+
+    public IOTask() {
+        super();
+    }
+
+    public IOTask(Dispatcher dispatcher) {
+        super(dispatcher);
+    }
+}

Added: incubator/pivot/branches/1.1/core/src/pivot/io/package.html
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/io/package.html?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/io/package.html (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/io/package.html Wed Mar 25 23:08:38 2009
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>Contains classes related to input/output operations.</p>
+</body>
+</html>

Added: incubator/pivot/branches/1.1/core/src/pivot/serialization/BinarySerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/core/src/pivot/serialization/BinarySerializer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/core/src/pivot/serialization/BinarySerializer.java (added)
+++ incubator/pivot/branches/1.1/core/src/pivot/serialization/BinarySerializer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008 VMware, 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.
+ */
+package pivot.serialization;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * Implementation of the {@link Serializer} interface that uses Java's
+ * internal serialization mechanism to read and write values. All values in the
+ * object hierarchy are required to implement {@link Serializable}.
+ *
+ * @author gbrown
+ */
+public class BinarySerializer implements Serializer<Object> {
+    public static final String MIME_TYPE = "application/x-java-serialized-object";
+    public static final String CLASS_PARAMETER = "class";
+
+    /**
+     * Reads a graph of serialized objects from an input stream.
+     */
+    public Object readObject(InputStream inputStream) throws IOException,
+        SerializationException {
+        if (inputStream == null) {
+            throw new IllegalArgumentException("inputStream is null.");
+        }
+
+        Object object = null;
+
+        try {
+            ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
+            object = objectInputStream.readObject();
+        } catch(ClassNotFoundException exception) {
+            throw new SerializationException(exception);
+        }
+
+        return object;
+    }
+
+    /**
+     * Writes a graph of serializable objects to an output stream.
+     */
+    public void writeObject(Object object, OutputStream outputStream)
+        throws IOException, SerializationException {
+        if (object == null) {
+            throw new IllegalArgumentException("object is null.");
+        }
+
+        if (outputStream == null) {
+            throw new IllegalArgumentException("outputStream is null.");
+        }
+
+        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
+        objectOutputStream.writeObject(object);
+    }
+
+    public String getMIMEType(Object object) {
+        String mimeType = MIME_TYPE;
+        if (object != null) {
+            mimeType += "; " + CLASS_PARAMETER + "=" + object.getClass().getName();
+        }
+
+        return mimeType;
+    }
+}