[med-svn] [libjung-java] 01/01: patch instead of using collections15

Michael Crusoe misterc-guest at moszumanska.debian.org
Sat Feb 21 20:47:17 UTC 2015


This is an automated email from the git hooks/post-receive script.

misterc-guest pushed a commit to branch master
in repository libjung-java.

commit 59a1802ab6274e48110f3c2f9c42c6ca8c262ff0
Author: Michael R. Crusoe <mcrusoe at msu.edu>
Date:   Sat Feb 21 15:13:31 2015 -0500

    patch instead of using collections15
---
 debian/control                                |     3 +-
 debian/javabuild                              |     1 -
 debian/libjung-java.jlibs                     |     1 -
 debian/patches/collections15                  | 53359 ------------------------
 debian/patches/series                         |     1 -
 debian/patches/use-apache-commons-collections |   113 +
 debian/rules                                  |    26 +-
 7 files changed, 128 insertions(+), 53376 deletions(-)

diff --git a/debian/control b/debian/control
index 856ffbc..8c0a1f1 100644
--- a/debian/control
+++ b/debian/control
@@ -7,7 +7,8 @@ Build-Depends: debhelper (>= 9),
                javahelper,
                unzip
 Build-Depends-Indep: default-jdk,
-                     libcolt-java
+                     libcolt-java,
+                     libcommons-collections4-java
 Standards-Version: 3.9.6
 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=debian-med/libjung-java.git
 Vcs-Git: git://anonscm.debian.org/debian-med/libjung-java.git
diff --git a/debian/javabuild b/debian/javabuild
index 8770b19..d4547fa 100644
--- a/debian/javabuild
+++ b/debian/javabuild
@@ -1,4 +1,3 @@
-collections15.jar collections15
 jung-api-2.0.1.jar jung-api-2.0.1-sources
 jung-algorithms-2.0.1.jar jung-algorithms-2.0.1-sources
 jung-graph-impl-2.0.1.jar jung-graph-impl-2.0.1-sources
diff --git a/debian/libjung-java.jlibs b/debian/libjung-java.jlibs
index 62d6571..96f5138 100644
--- a/debian/libjung-java.jlibs
+++ b/debian/libjung-java.jlibs
@@ -1,4 +1,3 @@
 jung-api-2.0.1.jar
-collections15.jar
 jung-algorithms-2.0.1.jar
 jung-graph-impl-2.0.1.jar
diff --git a/debian/patches/collections15 b/debian/patches/collections15
deleted file mode 100644
index b5a96a1..0000000
--- a/debian/patches/collections15
+++ /dev/null
@@ -1,53359 +0,0 @@
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/ArrayStack.java
-@@ -0,0 +1,195 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.ArrayList;
-+import java.util.EmptyStackException;
-+
-+/**
-+ * An implementation of the {@link java.util.Stack} API that is based on an
-+ * <code>ArrayList</code> instead of a <code>Vector</code>, so it is not
-+ * synchronized to protect against multi-threaded access.  The implementation
-+ * is therefore operates faster in environments where you do not need to
-+ * worry about multiple thread contention.
-+ * <p/>
-+ * The removal order of an <code>ArrayStack</code> is based on insertion
-+ * order: The most recently added element is removed first.  The iteration
-+ * order is <i>not</i> the same as the removal order.  The iterator returns
-+ * elements from the bottom up, whereas the {@link #remove()} method removes
-+ * them from the top down.
-+ * <p/>
-+ * Unlike <code>Stack</code>, <code>ArrayStack</code> accepts null entries.
-+ *
-+ * @author Craig R. McClanahan
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @see java.util.Stack
-+ * @since Commons Collections 1.0
-+ */
-+public class ArrayStack <E> extends ArrayList<E> implements Buffer<E> {
-+
-+    /**
-+     * Ensure serialization compatibility
-+     */
-+    private static final long serialVersionUID = 2130079159931574599L;
-+
-+    /**
-+     * Constructs a new empty <code>ArrayStack</code>. The initial size
-+     * is controlled by <code>ArrayList</code> and is currently 10.
-+     */
-+    public ArrayStack() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new empty <code>ArrayStack</code> with an initial size.
-+     *
-+     * @param initialSize the initial size to use
-+     * @throws IllegalArgumentException if the specified initial size
-+     *                                  is negative
-+     */
-+    public ArrayStack(int initialSize) {
-+        super(initialSize);
-+    }
-+
-+    /**
-+     * Return <code>true</code> if this stack is currently empty.
-+     * <p/>
-+     * This method exists for compatibility with <code>java.util.Stack</code>.
-+     * New users of this class should use <code>isEmpty</code> instead.
-+     *
-+     * @return true if the stack is currently empty
-+     */
-+    public boolean empty() {
-+        return isEmpty();
-+    }
-+
-+    /**
-+     * Returns the top item off of this stack without removing it.
-+     *
-+     * @return the top item on the stack
-+     * @throws EmptyStackException if the stack is empty
-+     */
-+    public E peek() throws EmptyStackException {
-+        int n = size();
-+        if (n <= 0) {
-+            throw new EmptyStackException();
-+        } else {
-+            return get(n - 1);
-+        }
-+    }
-+
-+    /**
-+     * Returns the n'th item down (zero-relative) from the top of this
-+     * stack without removing it.
-+     *
-+     * @param n the number of items down to go
-+     * @return the n'th item on the stack, zero relative
-+     * @throws EmptyStackException if there are not enough items on the
-+     *                             stack to satisfy this request
-+     */
-+    public E peek(int n) throws EmptyStackException {
-+        int m = (size() - n) - 1;
-+        if (m < 0) {
-+            throw new EmptyStackException();
-+        } else {
-+            return get(m);
-+        }
-+    }
-+
-+    /**
-+     * Pops the top item off of this stack and return it.
-+     *
-+     * @return the top item on the stack
-+     * @throws EmptyStackException if the stack is empty
-+     */
-+    public E pop() throws EmptyStackException {
-+        int n = size();
-+        if (n <= 0) {
-+            throw new EmptyStackException();
-+        } else {
-+            return remove(n - 1);
-+        }
-+    }
-+
-+    /**
-+     * Pushes a new item onto the top of this stack. The pushed item is also
-+     * returned. This is equivalent to calling <code>add</code>.
-+     *
-+     * @param item the item to be added
-+     * @return the item just pushed
-+     */
-+    public E push(E item) {
-+        add(item);
-+        return item;
-+    }
-+
-+    /**
-+     * Returns the one-based position of the distance from the top that the
-+     * specified object exists on this stack, where the top-most element is
-+     * considered to be at distance <code>1</code>.  If the object is not
-+     * present on the stack, return <code>-1</code> instead.  The
-+     * <code>equals()</code> method is used to compare to the items
-+     * in this stack.
-+     *
-+     * @param object the object to be searched for
-+     * @return the 1-based depth into the stack of the object, or -1 if not found
-+     */
-+    public int search(E object) {
-+        int i = size() - 1;        // Current index
-+        int n = 1;                 // Current distance
-+        while (i >= 0) {
-+            E current = get(i);
-+            if ((object == null && current == null) || (object != null && object.equals(current))) {
-+                return n;
-+            }
-+            i--;
-+            n++;
-+        }
-+        return -1;
-+    }
-+
-+    /**
-+     * Returns the element on the top of the stack.
-+     *
-+     * @return the element on the top of the stack
-+     * @throws BufferUnderflowException if the stack is empty
-+     */
-+    public E get() {
-+        int size = size();
-+        if (size == 0) {
-+            throw new BufferUnderflowException();
-+        }
-+        return get(size - 1);
-+    }
-+
-+    /**
-+     * Removes the element on the top of the stack.
-+     *
-+     * @return the removed element
-+     * @throws BufferUnderflowException if the stack is empty
-+     */
-+    public E remove() {
-+        int size = size();
-+        if (size == 0) {
-+            throw new BufferUnderflowException();
-+        }
-+        return remove(size - 1);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/Bag.java
-@@ -0,0 +1,221 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Set;
-+
-+/**
-+ * Defines a collection that counts the number of times an object appears in
-+ * the collection.
-+ * <p/>
-+ * Suppose you have a Bag that contains <code>{a, a, b, c}</code>.
-+ * Calling {@link #getCount(Object)} on <code>a</code> would return 2, while
-+ * calling {@link #uniqueSet()} would return <code>{a, b, c}</code>.
-+ * <p/>
-+ * <i>NOTE: This interface violates the {@link Collection} contract.</i>
-+ * The behavior specified in many of these methods is <i>not</i> the same
-+ * as the behavior specified by <code>Collection</code>.
-+ * The noncompliant methods are clearly marked with "(Violation)".
-+ * Exercise caution when using a bag as a <code>Collection</code>.
-+ * <p/>
-+ * This violation resulted from the original specification of this interface.
-+ * In an ideal world, the interface would be changed to fix the problems, however
-+ * it has been decided to maintain backwards compatibility instead.
-+ *
-+ * @author Chuck Burdick
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.0
-+ */
-+public interface Bag <E> extends Collection<E> {
-+
-+    /**
-+     * Returns the number of occurrences (cardinality) of the given
-+     * object currently in the bag. If the object does not exist in the
-+     * bag, return 0.
-+     *
-+     * @param object the object to search for
-+     * @return the number of occurrences of the object, zero if not found
-+     */
-+    int getCount(E object);
-+
-+    /**
-+     * <i>(Violation)</i>
-+     * Adds one copy the specified object to the Bag.
-+     * <p/>
-+     * If the object is already in the {@link #uniqueSet()} then increment its
-+     * count as reported by {@link #getCount(Object)}. Otherwise add it to the
-+     * {@link #uniqueSet()} and report its count as 1.
-+     * <p/>
-+     * Since this method always increases the size of the bag,
-+     * according to the {@link Collection#add(Object)} contract, it
-+     * should always return <code>true</code>.  Since it sometimes returns
-+     * <code>false</code>, this method violates the contract.
-+     *
-+     * @param object the object to add
-+     * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
-+     */
-+    boolean add(E object);
-+
-+    /**
-+     * Adds <code>nCopies</code> copies of the specified object to the Bag.
-+     * <p/>
-+     * If the object is already in the {@link #uniqueSet()} then increment its
-+     * count as reported by {@link #getCount(Object)}. Otherwise add it to the
-+     * {@link #uniqueSet()} and report its count as <code>nCopies</code>.
-+     *
-+     * @param object  the object to add
-+     * @param nCopies the number of copies to add
-+     * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
-+     */
-+    boolean add(E object, int nCopies);
-+
-+    /**
-+     * <i>(Violation)</i>
-+     * Removes all occurrences of the given object from the bag.
-+     * <p/>
-+     * This will also remove the object from the {@link #uniqueSet()}.
-+     * <p/>
-+     * According to the {@link Collection#remove(Object)} method,
-+     * this method should only remove the <i>first</i> occurrence of the
-+     * given object, not <i>all</i> occurrences.
-+     *
-+     * @return <code>true</code> if this call changed the collection
-+     */
-+    boolean remove(Object object);
-+
-+    /**
-+     * Removes <code>nCopies</code> copies of the specified object from the Bag.
-+     * <p/>
-+     * If the number of copies to remove is greater than the actual number of
-+     * copies in the Bag, no error is thrown.
-+     *
-+     * @param object  the object to remove
-+     * @param nCopies the number of copies to remove
-+     * @return <code>true</code> if this call changed the collection
-+     */
-+    boolean remove(E object, int nCopies);
-+
-+    /**
-+     * Returns a {@link Set} of unique elements in the Bag.
-+     * <p/>
-+     * Uniqueness constraints are the same as those in {@link java.util.Set}.
-+     *
-+     * @return the Set of unique Bag elements
-+     */
-+    Set<E> uniqueSet();
-+
-+    /**
-+     * Returns the total number of items in the bag across all types.
-+     *
-+     * @return the total size of the Bag
-+     */
-+    int size();
-+
-+    /**
-+     * <i>(Violation)</i>
-+     * Returns <code>true</code> if the bag contains all elements in
-+     * the given collection, respecting cardinality.  That is, if the
-+     * given collection <code>coll</code> contains <code>n</code> copies
-+     * of a given object, calling {@link #getCount(Object)} on that object must
-+     * be <code>>= n</code> for all <code>n</code> in <code>coll</code>.
-+     * <p/>
-+     * The {@link Collection#containsAll(Collection)} method specifies
-+     * that cardinality should <i>not</i> be respected; this method should
-+     * return true if the bag contains at least one of every object contained
-+     * in the given collection.
-+     *
-+     * @param coll the collection to check against
-+     * @return <code>true</code> if the Bag contains all the collection
-+     */
-+    boolean containsAll(Collection<?> coll);
-+
-+    /**
-+     * <i>(Violation)</i>
-+     * Remove all elements represented in the given collection,
-+     * respecting cardinality.  That is, if the given collection
-+     * <code>coll</code> contains <code>n</code> copies of a given object,
-+     * the bag will have <code>n</code> fewer copies, assuming the bag
-+     * had at least <code>n</code> copies to begin with.
-+     * <p/>
-+     * <P>The {@link Collection#removeAll(Collection)} method specifies
-+     * that cardinality should <i>not</i> be respected; this method should
-+     * remove <i>all</i> occurrences of every object contained in the
-+     * given collection.
-+     *
-+     * @param coll the collection to remove
-+     * @return <code>true</code> if this call changed the collection
-+     */
-+    boolean removeAll(Collection<?> coll);
-+
-+    /**
-+     * <i>(Violation)</i>
-+     * Remove any members of the bag that are not in the given
-+     * collection, respecting cardinality.  That is, if the given
-+     * collection <code>coll</code> contains <code>n</code> copies of a
-+     * given object and the bag has <code>m > n</code> copies, then
-+     * delete <code>m - n</code> copies from the bag.  In addition, if
-+     * <code>e</code> is an object in the bag but
-+     * <code>!coll.contains(e)</code>, then remove <code>e</code> and any
-+     * of its copies.
-+     * <p/>
-+     * <P>The {@link Collection#retainAll(Collection)} method specifies
-+     * that cardinality should <i>not</i> be respected; this method should
-+     * keep <i>all</i> occurrences of every object contained in the
-+     * given collection.
-+     *
-+     * @param coll the collection to retain
-+     * @return <code>true</code> if this call changed the collection
-+     */
-+    boolean retainAll(Collection<?> coll);
-+
-+    /**
-+     * Returns an {@link Iterator} over the entire set of members,
-+     * including copies due to cardinality. This iterator is fail-fast
-+     * and will not tolerate concurrent modifications.
-+     *
-+     * @return iterator over all elements in the Bag
-+     */
-+    Iterator<E> iterator();
-+
-+    // The following is not part of the formal Bag interface, however where possible
-+    // Bag implementations should follow these comments.
-+    //    /**
-+    //     * Compares this Bag to another.
-+    //     * This Bag equals another Bag if it contains the same number of occurrences of
-+    //     * the same elements.
-+    //     * This equals definition is compatible with the Set interface.
-+    //     *
-+    //     * @param obj  the Bag to compare to
-+    //     * @return true if equal
-+    //     */
-+    //    boolean equals(Object obj);
-+    //
-+    //    /**
-+    //     * Gets a hash code for the Bag compatible with the definition of equals.
-+    //     * The hash code is defined as the sum total of a hash code for each element.
-+    //     * The per element hash code is defined as
-+    //     * <code>(e==null ? 0 : e.hashCode()) ^ noOccurances)</code>.
-+    //     * This hash code definition is compatible with the Set interface.
-+    //     *
-+    //     * @return the hash code of the Bag
-+    //     */
-+    //    int hashCode();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BagUtils.java
-@@ -0,0 +1,236 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.bag.*;
-+
-+/**
-+ * Provides utility methods and decorators for
-+ * {@link Bag} and {@link SortedBag} instances.
-+ *
-+ * @author Paul Jack
-+ * @author Stephen Colebourne
-+ * @author Andrew Freeman
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public class BagUtils {
-+
-+    /**
-+     * An empty unmodifiable bag.
-+     */
-+    public static final Bag EMPTY_BAG = UnmodifiableBag.decorate(new HashBag());
-+
-+    /**
-+     * An empty unmodifiable sorted bag.
-+     */
-+    public static final Bag EMPTY_SORTED_BAG = UnmodifiableSortedBag.decorate(new TreeBag());
-+
-+    /**
-+     * Instantiation of BagUtils is not intended or required.
-+     * However, some tools require an instance to operate.
-+     */
-+    public BagUtils() {
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized (thread-safe) bag backed by the given bag.
-+     * In order to guarantee serial access, it is critical that all
-+     * access to the backing bag is accomplished through the returned bag.
-+     * <p/>
-+     * It is imperative that the user manually synchronize on the returned
-+     * bag when iterating over it:
-+     * <p/>
-+     * <pre>
-+     * Bag bag = BagUtils.synchronizedBag(new HashBag());
-+     * ...
-+     * synchronized(bag) {
-+     *     Iterator i = bag.iterator(); // Must be in synchronized block
-+     *     while (i.hasNext())
-+     *         foo(i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * Failure to follow this advice may result in non-deterministic
-+     * behavior.
-+     *
-+     * @param bag the bag to synchronize, must not be null
-+     * @return a synchronized bag backed by that bag
-+     * @throws IllegalArgumentException if the Bag is null
-+     */
-+    public static <E> Bag<E> synchronizedBag(Bag<E> bag) {
-+        return SynchronizedBag.decorate(bag);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable view of the given bag.  Any modification
-+     * attempts to the returned bag will raise an
-+     * {@link UnsupportedOperationException}.
-+     *
-+     * @param bag the bag whose unmodifiable view is to be returned, must not be null
-+     * @return an unmodifiable view of that bag
-+     * @throws IllegalArgumentException if the Bag is null
-+     */
-+    public static <E> Bag<E> unmodifiableBag(Bag<E> bag) {
-+        return UnmodifiableBag.decorate(bag);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) bag backed by the given bag.
-+     * <p/>
-+     * Only objects that pass the test in the given predicate can be added to the bag.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * It is important not to use the original bag after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param bag       the bag to predicate, must not be null
-+     * @param predicate the predicate for the bag, must not be null
-+     * @return a predicated bag backed by the given bag
-+     * @throws IllegalArgumentException if the Bag or Predicate is null
-+     */
-+    public static <E> Bag<E> predicatedBag(Bag<E> bag, Predicate<? super E> predicate) {
-+        return PredicatedBag.decorate(bag, predicate);
-+    }
-+
-+    /**
-+     * Returns a typed bag backed by the given bag.
-+     * <p/>
-+     * Only objects of the specified type can be added to the bag.
-+     *
-+     * @param bag  the bag to limit to a specific type, must not be null
-+     * @param type the type of objects which may be added to the bag
-+     * @return a typed bag backed by the specified bag
-+     * @deprecated Java 1.5 generics makes this method no longer useful.
-+     */
-+    public static <E> Bag<E> typedBag(Bag<E> bag, Class<E> type) {
-+        return TypedBag.decorate(bag, type);
-+    }
-+
-+    /**
-+     * Returns a transformed bag backed by the given bag.
-+     * <p/>
-+     * Each object is passed through the transformer as it is added to the
-+     * Bag. It is important not to use the original bag after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param bag         the bag to predicate, must not be null
-+     * @param transformer the transformer for the bag, must not be null
-+     * @return a transformed bag backed by the given bag
-+     * @throws IllegalArgumentException if the Bag or Transformer is null
-+     * @deprecated TransformedCollections are not type-safe in Java 1.5.
-+     */
-+    public static <I,O> Bag<O> transformedBag(Bag<I> bag, Transformer<I, O> transformer) {
-+        return TransformedBag.decorate(bag, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized (thread-safe) sorted bag backed by the given
-+     * sorted bag.
-+     * In order to guarantee serial access, it is critical that all
-+     * access to the backing bag is accomplished through the returned bag.
-+     * <p/>
-+     * It is imperative that the user manually synchronize on the returned
-+     * bag when iterating over it:
-+     * <p/>
-+     * <pre>
-+     * SortedBag bag = BagUtils.synchronizedSortedBag(new TreeBag());
-+     * ...
-+     * synchronized(bag) {
-+     *     Iterator i = bag.iterator(); // Must be in synchronized block
-+     *     while (i.hasNext())
-+     *         foo(i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * Failure to follow this advice may result in non-deterministic
-+     * behavior.
-+     *
-+     * @param bag the bag to synchronize, must not be null
-+     * @return a synchronized bag backed by that bag
-+     * @throws IllegalArgumentException if the SortedBag is null
-+     */
-+    public static <E> SortedBag<E> synchronizedSortedBag(SortedBag<E> bag) {
-+        return SynchronizedSortedBag.decorate(bag);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable view of the given sorted bag.  Any modification
-+     * attempts to the returned bag will raise an
-+     * {@link UnsupportedOperationException}.
-+     *
-+     * @param bag the bag whose unmodifiable view is to be returned, must not be null
-+     * @return an unmodifiable view of that bag
-+     * @throws IllegalArgumentException if the SortedBag is null
-+     */
-+    public static <E> SortedBag<E> unmodifiableSortedBag(SortedBag<E> bag) {
-+        return UnmodifiableSortedBag.decorate(bag);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) sorted bag backed by the given sorted bag.
-+     * <p/>
-+     * Only objects that pass the test in the given predicate can be added to the bag.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * It is important not to use the original bag after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param bag       the sorted bag to predicate, must not be null
-+     * @param predicate the predicate for the bag, must not be null
-+     * @return a predicated bag backed by the given bag
-+     * @throws IllegalArgumentException if the SortedBag or Predicate is null
-+     */
-+    public static <E> SortedBag<E> predicatedSortedBag(SortedBag<E> bag, Predicate<? super E> predicate) {
-+        return PredicatedSortedBag.decorate(bag, predicate);
-+    }
-+
-+    /**
-+     * Returns a typed sorted bag backed by the given bag.
-+     * <p/>
-+     * Only objects of the specified type can be added to the bag.
-+     *
-+     * @param bag  the bag to limit to a specific type, must not be null
-+     * @param type the type of objects which may be added to the bag
-+     * @return a typed bag backed by the specified bag
-+     * @deprecated Java 1.5 generics makes this method no longer useful.
-+     */
-+    public static <E> SortedBag<E> typedSortedBag(SortedBag<E> bag, Class<E> type) {
-+        return TypedSortedBag.decorate(bag, type);
-+    }
-+
-+    /**
-+     * Returns a transformed sorted bag backed by the given bag.
-+     * <p/>
-+     * Each object is passed through the transformer as it is added to the
-+     * Bag. It is important not to use the original bag after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param bag         the bag to predicate, must not be null
-+     * @param transformer the transformer for the bag, must not be null
-+     * @return a transformed bag backed by the given bag
-+     * @throws IllegalArgumentException if the Bag or Transformer is null
-+     * @deprecated This breaks the java.util.Collection interface in Java 1.5. It is recommended that it not be used.
-+     */
-+    public static <I,O> SortedBag<O> transformedSortedBag(SortedBag<I> bag, Transformer<I, O> transformer) {
-+        return TransformedSortedBag.decorate(bag, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BeanMap.java
-@@ -0,0 +1,733 @@
-+// GenericsNote: Converted to <String,Object>.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.keyvalue.AbstractMapEntry;
-+import org.apache.commons.collections15.list.UnmodifiableList;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.beans.BeanInfo;
-+import java.beans.IntrospectionException;
-+import java.beans.Introspector;
-+import java.beans.PropertyDescriptor;
-+import java.lang.reflect.Constructor;
-+import java.lang.reflect.InvocationTargetException;
-+import java.lang.reflect.Method;
-+import java.util.*;
-+
-+/**
-+ * An implementation of Map for JavaBeans which uses introspection to
-+ * get and put properties in the bean.
-+ * <p/>
-+ * If an exception occurs during attempts to get or set a property then the
-+ * property is considered non existent in the Map
-+ * <p/>
-+ *
-+ * @author James Strachan
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public class BeanMap extends AbstractMap<String, Object> implements Cloneable {
-+
-+    private transient Object bean;
-+
-+    private transient HashMap<String, Method> readMethods = new HashMap<String, Method>();
-+    private transient HashMap<String, Method> writeMethods = new HashMap<String, Method>();
-+    private transient HashMap<String, Class> types = new HashMap<String, Class>();
-+
-+    /**
-+     * An empty array.  Used to invoke accessors via reflection.
-+     */
-+    public static final Object[] NULL_ARGUMENTS = {};
-+
-+    /**
-+     * Maps primitive Class types to transformers.  The transformer
-+     * transform strings into the appropriate primitive wrapper.
-+     */
-+    public static HashMap defaultTransformers = new HashMap();
-+
-+    static {
-+        defaultTransformers.put(Boolean.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return Boolean.valueOf(input.toString());
-+            }
-+        });
-+        defaultTransformers.put(Character.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return new Character(input.toString().charAt(0));
-+            }
-+        });
-+        defaultTransformers.put(Byte.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return Byte.valueOf(input.toString());
-+            }
-+        });
-+        defaultTransformers.put(Short.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return Short.valueOf(input.toString());
-+            }
-+        });
-+        defaultTransformers.put(Integer.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return Integer.valueOf(input.toString());
-+            }
-+        });
-+        defaultTransformers.put(Long.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return Long.valueOf(input.toString());
-+            }
-+        });
-+        defaultTransformers.put(Float.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return Float.valueOf(input.toString());
-+            }
-+        });
-+        defaultTransformers.put(Double.TYPE, new Transformer() {
-+            public Object transform(Object input) {
-+                return Double.valueOf(input.toString());
-+            }
-+        });
-+    }
-+
-+
-+    // Constructors
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Constructs a new empty <code>BeanMap</code>.
-+     */
-+    public BeanMap() {
-+    }
-+
-+    /**
-+     * Constructs a new <code>BeanMap</code> that operates on the
-+     * specified bean.  If the given bean is <code>null</code>, then
-+     * this map will be empty.
-+     *
-+     * @param bean the bean for this map to operate on
-+     */
-+    public BeanMap(Object bean) {
-+        this.bean = bean;
-+        initialise();
-+    }
-+
-+    // Map interface
-+    //-------------------------------------------------------------------------
-+
-+    public String toString() {
-+        return "BeanMap<" + String.valueOf(bean) + ">";
-+    }
-+
-+    /**
-+     * Clone this bean map using the following process:
-+     * <p/>
-+     * <ul>
-+     * <li>If there is no underlying bean, return a cloned BeanMap without a
-+     * bean.
-+     * <p/>
-+     * <li>Since there is an underlying bean, try to instantiate a new bean of
-+     * the same type using Class.newInstance().
-+     * <p/>
-+     * <li>If the instantiation fails, throw a CloneNotSupportedException
-+     * <p/>
-+     * <li>Clone the bean map and set the newly instantiated bean as the
-+     * underlying bean for the bean map.
-+     * <p/>
-+     * <li>Copy each property that is both readable and writable from the
-+     * existing object to a cloned bean map.
-+     * <p/>
-+     * <li>If anything fails along the way, throw a
-+     * CloneNotSupportedException.
-+     * <p/>
-+     * <ul>
-+     */
-+    public Object clone() throws CloneNotSupportedException {
-+        BeanMap newMap = (BeanMap) super.clone();
-+
-+        if (bean == null) {
-+            // no bean, just an empty bean map at the moment.  return a newly
-+            // cloned and empty bean map.
-+            return newMap;
-+        }
-+
-+        Object newBean = null;
-+        Class beanClass = null;
-+        try {
-+            beanClass = bean.getClass();
-+            newBean = beanClass.newInstance();
-+        } catch (Exception e) {
-+            // unable to instantiate
-+            throw new CloneNotSupportedException("Unable to instantiate the underlying bean \"" + beanClass.getName() + "\": " + e);
-+        }
-+
-+        try {
-+            newMap.setBean(newBean);
-+        } catch (Exception exception) {
-+            throw new CloneNotSupportedException("Unable to set bean in the cloned bean map: " + exception);
-+        }
-+
-+        try {
-+            // copy only properties that are readable and writable.  If its
-+            // not readable, we can't get the value from the old map.  If
-+            // its not writable, we can't write a value into the new map.
-+            Iterator<String> readableKeys = readMethods.keySet().iterator();
-+            while (readableKeys.hasNext()) {
-+                String key = readableKeys.next();
-+                if (getWriteMethod(key) != null) {
-+                    newMap.put(key, get(key));
-+                }
-+            }
-+        } catch (Exception exception) {
-+            throw new CloneNotSupportedException("Unable to copy bean values to cloned bean map: " + exception);
-+        }
-+
-+        return newMap;
-+    }
-+
-+    /**
-+     * Puts all of the writable properties from the given BeanMap into this
-+     * BeanMap. Read-only and Write-only properties will be ignored.
-+     *
-+     * @param map the BeanMap whose properties to put
-+     */
-+    public void putAllWriteable(BeanMap map) {
-+        Iterator<String> readableKeys = map.readMethods.keySet().iterator();
-+        while (readableKeys.hasNext()) {
-+            String key = readableKeys.next();
-+            if (getWriteMethod(key) != null) {
-+                this.put(key, map.get(key));
-+            }
-+        }
-+    }
-+
-+
-+    /**
-+     * This method reinitializes the bean map to have default values for the
-+     * bean's properties.  This is accomplished by constructing a new instance
-+     * of the bean which the map uses as its underlying data source.  This
-+     * behavior for <code>clear()</code> differs from the Map contract in that
-+     * the mappings are not actually removed from the map (the mappings for a
-+     * BeanMap are fixed).
-+     */
-+    public void clear() {
-+        if (bean == null) return;
-+
-+        Class beanClass = null;
-+        try {
-+            beanClass = bean.getClass();
-+            bean = beanClass.newInstance();
-+        } catch (Exception e) {
-+            throw new UnsupportedOperationException("Could not create new instance of class: " + beanClass);
-+        }
-+    }
-+
-+    /**
-+     * Returns true if the bean defines a property with the given name.
-+     * <p/>
-+     * The given name must be a <code>String</code>; if not, this method
-+     * returns false. This method will also return false if the bean
-+     * does not define a property with that name.
-+     * <p/>
-+     * Write-only properties will not be matched as the test operates against
-+     * property read methods.
-+     *
-+     * @param name the name of the property to check
-+     * @return false if the given name is null or is not a <code>String</code>;
-+     *         false if the bean does not define a property with that name; or
-+     *         true if the bean does define a property with that name
-+     */
-+    public boolean containsKey(String name) {
-+        Method method = getReadMethod(name);
-+        return method != null;
-+    }
-+
-+    /**
-+     * Returns true if the bean defines a property whose current value is
-+     * the given object.
-+     *
-+     * @param value the value to check
-+     * @return false  true if the bean has at least one property whose
-+     *         current value is that object, false otherwise
-+     */
-+    public boolean containsValue(Object value) {
-+        // use default implementation
-+        return super.containsValue(value);
-+    }
-+
-+    /**
-+     * Returns the value of the bean's property with the given name.
-+     * <p/>
-+     * The given name must be a {@link String} and must not be
-+     * null; otherwise, this method returns <code>null</code>.
-+     * If the bean defines a property with the given name, the value of
-+     * that property is returned.  Otherwise, <code>null</code> is
-+     * returned.
-+     * <p/>
-+     * Write-only properties will not be matched as the test operates against
-+     * property read methods.
-+     *
-+     * @param name the name of the property whose value to return
-+     * @return the value of the property with that name
-+     */
-+    public Object get(String name) {
-+        if (bean != null) {
-+            Method method = getReadMethod(name);
-+            if (method != null) {
-+                try {
-+                    return method.invoke(bean, NULL_ARGUMENTS);
-+                } catch (IllegalAccessException e) {
-+                    logWarn(e);
-+                } catch (IllegalArgumentException e) {
-+                    logWarn(e);
-+                } catch (InvocationTargetException e) {
-+                    logWarn(e);
-+                } catch (NullPointerException e) {
-+                    logWarn(e);
-+                }
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Sets the bean property with the given name to the given value.
-+     *
-+     * @param name  the name of the property to set
-+     * @param value the value to set that property to
-+     * @return the previous value of that property
-+     * @throws IllegalArgumentException if the given name is null;
-+     *                                  if the given name is not a {@link String}; if the bean doesn't
-+     *                                  define a property with that name; or if the bean property with
-+     *                                  that name is read-only
-+     */
-+    public Object put(String name, Object value) throws IllegalArgumentException, ClassCastException {
-+        if (bean != null) {
-+            Object oldValue = get(name);
-+            Method method = getWriteMethod(name);
-+            if (method == null) {
-+                throw new IllegalArgumentException("The bean of type: " + bean.getClass().getName() + " has no property called: " + name);
-+            }
-+            try {
-+                Object[] arguments = createWriteMethodArguments(method, value);
-+                method.invoke(bean, arguments);
-+
-+                Object newValue = get(name);
-+                firePropertyChange(name, oldValue, newValue);
-+            } catch (InvocationTargetException e) {
-+                logInfo(e);
-+                throw new IllegalArgumentException(e.getMessage());
-+            } catch (IllegalAccessException e) {
-+                logInfo(e);
-+                throw new IllegalArgumentException(e.getMessage());
-+            }
-+            return oldValue;
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Returns the number of properties defined by the bean.
-+     *
-+     * @return the number of properties defined by the bean
-+     */
-+    public int size() {
-+        return readMethods.size();
-+    }
-+
-+
-+    /**
-+     * Get the keys for this BeanMap.
-+     * <p/>
-+     * Write-only properties are <b>not</b> included in the returned set of
-+     * property names, although it is possible to set their value and to get
-+     * their type.
-+     *
-+     * @return BeanMap keys.  The Set returned by this method is not
-+     *         modifiable.
-+     */
-+    public Set<String> keySet() {
-+        return UnmodifiableSet.decorate(readMethods.keySet());
-+    }
-+
-+    /**
-+     * Gets a Set of MapEntry objects that are the mappings for this BeanMap.
-+     * <p/>
-+     * Each MapEntry can be set but not removed.
-+     *
-+     * @return the unmodifiable set of mappings
-+     */
-+    public Set<Entry<String, Object>> entrySet() {
-+        return UnmodifiableSet.decorate(new AbstractSet<Entry<String, Object>>() {
-+            public Iterator<Entry<String, Object>> iterator() {
-+                return entryIterator();
-+            }
-+
-+            public int size() {
-+                return BeanMap.this.readMethods.size();
-+            }
-+        });
-+    }
-+
-+    /**
-+     * Returns the values for the BeanMap.
-+     *
-+     * @return values for the BeanMap.  The returned collection is not
-+     *         modifiable.
-+     */
-+    public Collection<Object> values() {
-+        ArrayList answer = new ArrayList(readMethods.size());
-+        for (Iterator iter = valueIterator(); iter.hasNext();) {
-+            answer.add(iter.next());
-+        }
-+        return UnmodifiableList.decorate(answer);
-+    }
-+
-+
-+    // Helper methods
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Returns the type of the property with the given name.
-+     *
-+     * @param name the name of the property
-+     * @return the type of the property, or <code>null</code> if no such
-+     *         property exists
-+     */
-+    public Class getType(String name) {
-+        return (Class) types.get(name);
-+    }
-+
-+    /**
-+     * Convenience method for getting an iterator over the keys.
-+     * <p/>
-+     * Write-only properties will not be returned in the iterator.
-+     *
-+     * @return an iterator over the keys
-+     */
-+    public Iterator<String> keyIterator() {
-+        return readMethods.keySet().iterator();
-+    }
-+
-+    /**
-+     * Convenience method for getting an iterator over the values.
-+     *
-+     * @return an iterator over the values
-+     */
-+    public Iterator<Object> valueIterator() {
-+        final Iterator<String> iter = keyIterator();
-+        return new Iterator<Object>() {
-+            public boolean hasNext() {
-+                return iter.hasNext();
-+            }
-+
-+            public Object next() {
-+                Object key = iter.next();
-+                return get(key);
-+            }
-+
-+            public void remove() {
-+                throw new UnsupportedOperationException("remove() not supported for BeanMap");
-+            }
-+        };
-+    }
-+
-+    /**
-+     * Convenience method for getting an iterator over the entries.
-+     *
-+     * @return an iterator over the entries
-+     */
-+    public Iterator<Entry<String, Object>> entryIterator() {
-+        final Iterator<String> iter = keyIterator();
-+        return new Iterator<Entry<String, Object>>() {
-+            public boolean hasNext() {
-+                return iter.hasNext();
-+            }
-+
-+            public Entry<String, Object> next() {
-+                String key = iter.next();
-+                Object value = get(key);
-+                return new MyMapEntry(BeanMap.this, key, value);
-+            }
-+
-+            public void remove() {
-+                throw new UnsupportedOperationException("remove() not supported for BeanMap");
-+            }
-+        };
-+    }
-+
-+
-+    // Properties
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Returns the bean currently being operated on.  The return value may
-+     * be null if this map is empty.
-+     *
-+     * @return the bean being operated on by this map
-+     */
-+    public Object getBean() {
-+        return bean;
-+    }
-+
-+    /**
-+     * Sets the bean to be operated on by this map.  The given value may
-+     * be null, in which case this map will be empty.
-+     *
-+     * @param newBean the new bean to operate on
-+     */
-+    public void setBean(Object newBean) {
-+        bean = newBean;
-+        reinitialise();
-+    }
-+
-+    /**
-+     * Returns the accessor for the property with the given name.
-+     *
-+     * @param name the name of the property
-+     * @return the accessor method for the property, or null
-+     */
-+    public Method getReadMethod(String name) {
-+        return readMethods.get(name);
-+    }
-+
-+    /**
-+     * Returns the mutator for the property with the given name.
-+     *
-+     * @param name the name of the property
-+     * @return the mutator method for the property, or null
-+     */
-+    public Method getWriteMethod(String name) {
-+        return (Method) writeMethods.get(name);
-+    }
-+
-+
-+    // Implementation methods
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Reinitializes this bean.  Called during {@link #setBean(Object)}.
-+     * Does introspection to find properties.
-+     */
-+    protected void reinitialise() {
-+        readMethods.clear();
-+        writeMethods.clear();
-+        types.clear();
-+        initialise();
-+    }
-+
-+    private void initialise() {
-+        if (getBean() == null) return;
-+
-+        Class beanClass = getBean().getClass();
-+        try {
-+            //BeanInfo beanInfo = Introspector.getBeanInfo( bean, null );
-+            BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
-+            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
-+            if (propertyDescriptors != null) {
-+                for (int i = 0; i < propertyDescriptors.length; i++) {
-+                    PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
-+                    if (propertyDescriptor != null) {
-+                        String name = propertyDescriptor.getName();
-+                        Method readMethod = propertyDescriptor.getReadMethod();
-+                        Method writeMethod = propertyDescriptor.getWriteMethod();
-+                        Class aType = propertyDescriptor.getPropertyType();
-+
-+                        if (readMethod != null) {
-+                            readMethods.put(name, readMethod);
-+                        }
-+                        if (writeMethods != null) {
-+                            writeMethods.put(name, writeMethod);
-+                        }
-+                        types.put(name, aType);
-+                    }
-+                }
-+            }
-+        } catch (IntrospectionException e) {
-+            logWarn(e);
-+        }
-+    }
-+
-+    /**
-+     * Called during a successful {@link #put(Object,Object)} operation.
-+     * Default implementation does nothing.  Override to be notified of
-+     * property changes in the bean caused by this map.
-+     *
-+     * @param key      the name of the property that changed
-+     * @param oldValue the old value for that property
-+     * @param newValue the new value for that property
-+     */
-+    protected void firePropertyChange(String key, Object oldValue, Object newValue) {
-+    }
-+
-+    // Implementation classes
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Map entry used by {@link BeanMap}.
-+     */
-+    protected static class MyMapEntry extends AbstractMapEntry<String, Object> {
-+        private BeanMap owner;
-+
-+        /**
-+         * Constructs a new <code>MyMapEntry</code>.
-+         *
-+         * @param owner the BeanMap this entry belongs to
-+         * @param key   the key for this entry
-+         * @param value the value for this entry
-+         */
-+        protected MyMapEntry(BeanMap owner, String key, Object value) {
-+            super(key, value);
-+            this.owner = owner;
-+        }
-+
-+        /**
-+         * Sets the value.
-+         *
-+         * @param value the new value for the entry
-+         * @return the old value for the entry
-+         */
-+        public Object setValue(Object value) {
-+            String key = getKey();
-+            Object oldValue = owner.get(key);
-+
-+            owner.put(key, value);
-+            Object newValue = owner.get(key);
-+            super.setValue(newValue);
-+            return oldValue;
-+        }
-+    }
-+
-+    /**
-+     * Creates an array of parameters to pass to the given mutator method.
-+     * If the given object is not the right type to pass to the method
-+     * directly, it will be converted using {@link #convertType(Class,Object)}.
-+     *
-+     * @param method the mutator method
-+     * @param value  the value to pass to the mutator method
-+     * @return an array containing one object that is either the given value
-+     *         or a transformed value
-+     * @throws IllegalAccessException   if {@link #convertType(Class,Object)}
-+     *                                  raises it
-+     * @throws IllegalArgumentException if any other exception is raised
-+     *                                  by {@link #convertType(Class,Object)}
-+     */
-+    protected Object[] createWriteMethodArguments(Method method, Object value) throws IllegalAccessException, ClassCastException {
-+        try {
-+            if (value != null) {
-+                Class[] types = method.getParameterTypes();
-+                if (types != null && types.length > 0) {
-+                    Class paramType = types[0];
-+                    if (!paramType.isAssignableFrom(value.getClass())) {
-+                        value = convertType(paramType, value);
-+                    }
-+                }
-+            }
-+            Object[] answer = {value};
-+            return answer;
-+        } catch (InvocationTargetException e) {
-+            logInfo(e);
-+            throw new IllegalArgumentException(e.getMessage());
-+        } catch (InstantiationException e) {
-+            logInfo(e);
-+            throw new IllegalArgumentException(e.getMessage());
-+        }
-+    }
-+
-+    /**
-+     * Converts the given value to the given type.  First, reflection is
-+     * is used to find a public constructor declared by the given class
-+     * that takes one argument, which must be the precise type of the
-+     * given value.  If such a constructor is found, a new object is
-+     * created by passing the given value to that constructor, and the
-+     * newly constructed object is returned.<P>
-+     * <p/>
-+     * If no such constructor exists, and the given type is a primitive
-+     * type, then the given value is converted to a string using its
-+     * {@link Object#toString() toString()} method, and that string is
-+     * parsed into the correct primitive type using, for instance,
-+     * {@link Integer#valueOf(String)} to convert the string into an
-+     * <code>int</code>.<P>
-+     * <p/>
-+     * If no special constructor exists and the given type is not a
-+     * primitive type, this method returns the original value.
-+     *
-+     * @param newType the type to convert the value to
-+     * @param value   the value to convert
-+     * @return the converted value
-+     * @throws NumberFormatException     if newType is a primitive type, and
-+     *                                   the string representation of the given value cannot be converted
-+     *                                   to that type
-+     * @throws InstantiationException    if the constructor found with
-+     *                                   reflection raises it
-+     * @throws InvocationTargetException if the constructor found with
-+     *                                   reflection raises it
-+     * @throws IllegalAccessException    never
-+     * @throws IllegalArgumentException  never
-+     */
-+    protected Object convertType(Class newType, Object value) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-+
-+        // try call constructor
-+        Class[] types = {value.getClass()};
-+        try {
-+            Constructor constructor = newType.getConstructor(types);
-+            Object[] arguments = {value};
-+            return constructor.newInstance(arguments);
-+        } catch (NoSuchMethodException e) {
-+            // try using the transformers
-+            Transformer transformer = getTypeTransformer(newType);
-+            if (transformer != null) {
-+                return transformer.transform(value);
-+            }
-+            return value;
-+        }
-+    }
-+
-+    /**
-+     * Returns a transformer for the given primitive type.
-+     *
-+     * @param aType the primitive type whose transformer to return
-+     * @return a transformer that will convert strings into that type,
-+     *         or null if the given type is not a primitive type
-+     */
-+    protected Transformer getTypeTransformer(Class aType) {
-+        return (Transformer) defaultTransformers.get(aType);
-+    }
-+
-+    /**
-+     * Logs the given exception to <code>System.out</code>.  Used to display
-+     * warnings while accessing/mutating the bean.
-+     *
-+     * @param ex the exception to log
-+     */
-+    protected void logInfo(Exception ex) {
-+        // Deliberately do not use LOG4J or Commons Logging to avoid dependencies
-+        System.out.println("INFO: Exception: " + ex);
-+    }
-+
-+    /**
-+     * Logs the given exception to <code>System.err</code>.  Used to display
-+     * errors while accessing/mutating the bean.
-+     *
-+     * @param ex the exception to log
-+     */
-+    protected void logWarn(Exception ex) {
-+        // Deliberately do not use LOG4J or Commons Logging to avoid dependencies
-+        System.out.println("WARN: Exception: " + ex);
-+        ex.printStackTrace();
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BidiMap.java
-@@ -0,0 +1,161 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Set;
-+
-+/**
-+ * Defines a map that allows bidirectional lookup between key and values.
-+ * <p/>
-+ * This extended <code>Map</code> represents a mapping where a key may
-+ * lookup a value and a value may lookup a key with equal ease.
-+ * This interface extends <code>Map</code> and so may be used anywhere a map
-+ * is required. The interface provides an inverse map view, enabling
-+ * full access to both directions of the <code>BidiMap</code>.
-+ * <p/>
-+ * Implementations should allow a value to be looked up from a key and
-+ * a key to be looked up from a value with equal performance.
-+ * <p/>
-+ * This map enforces the restriction that there is a 1:1 relation between
-+ * keys and values, meaning that multiple keys cannot map to the same value.
-+ * This is required so that "inverting" the map results in a map without
-+ * duplicate keys. See the {@link #put} method description for more information.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface BidiMap <K,V> extends IterableMap<K, V> {
-+
-+    /**
-+     * Obtains a <code>MapIterator</code> over the map.
-+     * <p/>
-+     * A map iterator is an efficient way of iterating over maps.
-+     * It does not require that the map is stored using Map Entry objects
-+     * which can increase performance.
-+     * <pre>
-+     * BidiMap map = new DualHashBidiMap();
-+     * MapIterator it = map.mapIterator();
-+     * while (it.hasNext()) {
-+     *   Object key = it.next();
-+     *   Object value = it.getValue();
-+     *   it.setValue("newValue");
-+     * }
-+     * </pre>
-+     *
-+     * @return a map iterator
-+     */
-+    MapIterator<K, V> mapIterator();
-+
-+    /**
-+     * Puts the key-value pair into the map, replacing any previous pair.
-+     * <p/>
-+     * When adding a key-value pair, the value may already exist in the map
-+     * against a different key. That mapping is removed, to ensure that the
-+     * value only occurs once in the inverse map.
-+     * <pre>
-+     *  BidiMap map1 = new DualHashBidiMap();
-+     *  map.put("A","B");  // contains A mapped to B, as per Map
-+     *  map.put("A","C");  // contains A mapped to C, as per Map
-+     * <p/>
-+     *  BidiMap map2 = new DualHashBidiMap();
-+     *  map.put("A","B");  // contains A mapped to B, as per Map
-+     *  map.put("C","B");  // contains C mapped to B, key A is removed
-+     * </pre>
-+     *
-+     * @param key   the key to store
-+     * @param value the value to store
-+     * @return the previous value mapped to this key
-+     * @throws UnsupportedOperationException if the <code>put</code> method is not supported
-+     * @throws ClassCastException            (optional) if the map limits the type of the
-+     *                                       value and the specified value is inappropriate
-+     * @throws IllegalArgumentException      (optional) if the map limits the values
-+     *                                       in some way and the value was invalid
-+     * @throws NullPointerException          (optional) if the map limits the values to
-+     *                                       non-null and null was specified
-+     */
-+    V put(K key, V value);
-+
-+    /**
-+     * Gets the key that is currently mapped to the specified value.
-+     * <p/>
-+     * If the value is not contained in the map, <code>null</code> is returned.
-+     * <p/>
-+     * Implementations should seek to make this method perform equally as well
-+     * as <code>get(Object)</code>.
-+     *
-+     * @param value the value to find the key for
-+     * @return the mapped key, or <code>null</code> if not found
-+     * @throws ClassCastException   (optional) if the map limits the type of the
-+     *                              value and the specified value is inappropriate
-+     * @throws NullPointerException (optional) if the map limits the values to
-+     *                              non-null and null was specified
-+     */
-+    K getKey(Object value);
-+
-+    /**
-+     * Removes the key-value pair that is currently mapped to the specified
-+     * value (optional operation).
-+     * <p/>
-+     * If the value is not contained in the map, <code>null</code> is returned.
-+     * <p/>
-+     * Implementations should seek to make this method perform equally as well
-+     * as <code>remove(Object)</code>.
-+     *
-+     * @param value the value to find the key-value pair for
-+     * @return the key that was removed, <code>null</code> if nothing removed
-+     * @throws ClassCastException            (optional) if the map limits the type of the
-+     *                                       value and the specified value is inappropriate
-+     * @throws NullPointerException          (optional) if the map limits the values to
-+     *                                       non-null and null was specified
-+     * @throws UnsupportedOperationException if this method is not supported
-+     *                                       by the implementation
-+     */
-+    K removeValue(Object value);
-+
-+    /**
-+     * Gets a view of this map where the keys and values are reversed.
-+     * <p/>
-+     * Changes to one map will be visible in the other and vice versa.
-+     * This enables both directions of the map to be accessed as a <code>Map</code>.
-+     * <p/>
-+     * Implementations should seek to avoid creating a new object every time this
-+     * method is called. See <code>AbstractMap.values()</code> etc. Calling this
-+     * method on the inverse map should return the original.
-+     *
-+     * @return an inverted bidirectional map
-+     */
-+    BidiMap<V, K> inverseBidiMap();
-+
-+
-+    /**
-+     * Returns a set view of the values contained in this BidiMap.  The
-+     * set is backed by the map, so changes to the map are reflected in
-+     * the collection, and vice-versa.  If the map is modified while an
-+     * iteration over the collection is in progress (except through the
-+     * iterator's own <tt>remove</tt> operation), the results of the
-+     * iteration are undefined.  The collection supports element removal,
-+     * which removes the corresponding mapping from the map, via the
-+     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
-+     * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt> operations.
-+     * It does not support the add or <tt>addAll</tt> operations.
-+     *
-+     * @return a Set view of the values contained in this map.
-+     */
-+    Set<V> values();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BoundedCollection.java
-@@ -0,0 +1,51 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Collection;
-+
-+/**
-+ * Defines a collection that is bounded in size.
-+ * <p/>
-+ * The size of the collection can vary, but it can never exceed a preset
-+ * maximum number of elements. This interface allows the querying of details
-+ * associated with the maximum number of elements.
-+ *
-+ * @author Matt Hall, John Watkinson, Herve Quiroz
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @see CollectionUtils#isFull
-+ * @see CollectionUtils#maxSize
-+ * @since Commons Collections 3.0
-+ */
-+public interface BoundedCollection <E> extends Collection<E> {
-+
-+    /**
-+     * Returns true if this collection is full and no new elements can be added.
-+     *
-+     * @return <code>true</code> if the collection is full
-+     */
-+    boolean isFull();
-+
-+    /**
-+     * Gets the maximum size of the collection (the bound).
-+     *
-+     * @return the maximum number of elements the collection can hold
-+     */
-+    int maxSize();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BoundedMap.java
-@@ -0,0 +1,48 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Map;
-+
-+/**
-+ * Defines a map that is bounded in size.
-+ * <p/>
-+ * The size of the map can vary, but it can never exceed a preset
-+ * maximum number of elements. This interface allows the querying of details
-+ * associated with the maximum number of elements.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface BoundedMap <K,V> extends Map<K, V> {
-+
-+    /**
-+     * Returns true if this map is full and no new elements can be added.
-+     *
-+     * @return <code>true</code> if the map is full
-+     */
-+    boolean isFull();
-+
-+    /**
-+     * Gets the maximum size of the map (the bound).
-+     *
-+     * @return the maximum number of elements the map can hold
-+     */
-+    int maxSize();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/Buffer.java
-@@ -0,0 +1,63 @@
-+// // GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Collection;
-+
-+/**
-+ * Defines a collection that allows objects to be removed in some well-defined order.
-+ * <p/>
-+ * The removal order can be based on insertion order (eg, a FIFO queue or a
-+ * LIFO stack), on access order (eg, an LRU cache), on some arbitrary comparator
-+ * (eg, a priority queue) or on any other well-defined ordering.
-+ * <p/>
-+ * Note that the removal order is not necessarily the same as the iteration
-+ * order.  A <code>Buffer</code> implementation may have equivalent removal
-+ * and iteration orders, but this is not required.
-+ * <p/>
-+ * This interface does not specify any behavior for
-+ * {@link Object#equals(Object)} and {@link Object#hashCode} methods.  It
-+ * is therefore possible for a <code>Buffer</code> implementation to also
-+ * also implement {@link java.util.List}, {@link java.util.Set} or
-+ * {@link Bag}.
-+ *
-+ * @author Avalon
-+ * @author Berin Loritsch
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public interface Buffer <E> extends Collection<E> {
-+
-+    /**
-+     * Gets and removes the next object from the buffer.
-+     *
-+     * @return the next object in the buffer, which is also removed
-+     * @throws BufferUnderflowException if the buffer is already empty
-+     */
-+    E remove();
-+
-+    /**
-+     * Gets the next object from the buffer without removing it.
-+     *
-+     * @return the next object in the buffer, which is not removed
-+     * @throws BufferUnderflowException if the buffer is empty
-+     */
-+    E get();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BufferOverflowException.java
-@@ -0,0 +1,75 @@
-+// GenericsNote: No conversion needed.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * The BufferOverflowException is used when the buffer's capacity has been
-+ * exceeded.
-+ *
-+ * @author Avalon
-+ * @author <a href="mailto:bloritsch at apache.org">Berin Loritsch</a>
-+ * @author <a href="mailto:jefft at apache.org">Jeff Turner</a>
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public class BufferOverflowException extends RuntimeException {
-+
-+    /**
-+     * The root cause throwable
-+     */
-+    private final Throwable throwable;
-+
-+    /**
-+     * Constructs a new <code>BufferOverflowException</code>.
-+     */
-+    public BufferOverflowException() {
-+        super();
-+        throwable = null;
-+    }
-+
-+    /**
-+     * Construct a new <code>BufferOverflowException</code>.
-+     *
-+     * @param message the detail message for this exception
-+     */
-+    public BufferOverflowException(String message) {
-+        this(message, null);
-+    }
-+
-+    /**
-+     * Construct a new <code>BufferOverflowException</code>.
-+     *
-+     * @param message   the detail message for this exception
-+     * @param exception the root cause of the exception
-+     */
-+    public BufferOverflowException(String message, Throwable exception) {
-+        super(message);
-+        throwable = exception;
-+    }
-+
-+    /**
-+     * Gets the root cause of the exception.
-+     *
-+     * @return the root cause
-+     */
-+    public final Throwable getCause() {
-+        return throwable;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BufferUnderflowException.java
-@@ -0,0 +1,78 @@
-+// GenericsNote: No conversion necessary.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * The BufferUnderflowException is used when the buffer is already empty.
-+ * <p/>
-+ * NOTE: From version 3.0, this exception extends NoSuchElementException.
-+ *
-+ * @author Avalon
-+ * @author Berin Loritsch
-+ * @author Jeff Turner
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public class BufferUnderflowException extends NoSuchElementException {
-+
-+    /**
-+     * The root cause throwable
-+     */
-+    private final Throwable throwable;
-+
-+    /**
-+     * Constructs a new <code>BufferUnderflowException</code>.
-+     */
-+    public BufferUnderflowException() {
-+        super();
-+        throwable = null;
-+    }
-+
-+    /**
-+     * Construct a new <code>BufferUnderflowException</code>.
-+     *
-+     * @param message the detail message for this exception
-+     */
-+    public BufferUnderflowException(String message) {
-+        this(message, null);
-+    }
-+
-+    /**
-+     * Construct a new <code>BufferUnderflowException</code>.
-+     *
-+     * @param message   the detail message for this exception
-+     * @param exception the root cause of the exception
-+     */
-+    public BufferUnderflowException(String message, Throwable exception) {
-+        super(message);
-+        throwable = exception;
-+    }
-+
-+    /**
-+     * Gets the root cause of the exception.
-+     *
-+     * @return the root cause
-+     */
-+    public final Throwable getCause() {
-+        return throwable;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/BufferUtils.java
-@@ -0,0 +1,142 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.buffer.*;
-+
-+/**
-+ * Provides utility methods and decorators for {@link Buffer} instances.
-+ *
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public class BufferUtils {
-+
-+    /**
-+     * An empty unmodifiable buffer.
-+     */
-+    public static final Buffer EMPTY_BUFFER = UnmodifiableBuffer.decorate(new ArrayStack(1));
-+
-+    /**
-+     * <code>BufferUtils</code> should not normally be instantiated.
-+     */
-+    public BufferUtils() {
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized buffer backed by the given buffer.
-+     * Much like the synchronized collections15 returned by
-+     * {@link java.util.Collections}, you must manually synchronize on
-+     * the returned buffer's iterator to avoid non-deterministic behavior:
-+     * <p/>
-+     * <pre>
-+     * Buffer b = BufferUtils.synchronizedBuffer(myBuffer);
-+     * synchronized (b) {
-+     *     Iterator i = b.iterator();
-+     *     while (i.hasNext()) {
-+     *         process (i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     *
-+     * @param buffer the buffer to synchronize, must not be null
-+     * @return a synchronized buffer backed by that buffer
-+     * @throws IllegalArgumentException if the Buffer is null
-+     */
-+    public static <E> Buffer<E> synchronizedBuffer(Buffer<E> buffer) {
-+        return SynchronizedBuffer.decorate(buffer);
-+    }
-+
-+    /**
-+     * Returns a synchronized buffer backed by the given buffer that will
-+     * block on {@link Buffer#get()} and {@link Buffer#remove()} operations.
-+     * If the buffer is empty, then the {@link Buffer#get()} and
-+     * {@link Buffer#remove()} operations will block until new elements
-+     * are added to the buffer, rather than immediately throwing a
-+     * <code>BufferUnderflowException</code>.
-+     *
-+     * @param buffer the buffer to synchronize, must not be null
-+     * @return a blocking buffer backed by that buffer
-+     * @throws IllegalArgumentException if the Buffer is null
-+     */
-+    public static <E> Buffer<E> blockingBuffer(Buffer<E> buffer) {
-+        return BlockingBuffer.decorate(buffer);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable buffer backed by the given buffer.
-+     *
-+     * @param buffer the buffer to make unmodifiable, must not be null
-+     * @return an unmodifiable buffer backed by that buffer
-+     * @throws IllegalArgumentException if the Buffer is null
-+     */
-+    public static <E> Buffer<E> unmodifiableBuffer(Buffer<E> buffer) {
-+        return UnmodifiableBuffer.decorate(buffer);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) buffer backed by the given buffer.
-+     * <p/>
-+     * Only objects that pass the test in the given predicate can be added to the buffer.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * It is important not to use the original buffer after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param buffer    the buffer to predicate, must not be null
-+     * @param predicate the predicate used to evaluate new elements, must not be null
-+     * @return a predicated buffer
-+     * @throws IllegalArgumentException if the Buffer or Predicate is null
-+     */
-+    public static <E> Buffer<E> predicatedBuffer(Buffer<E> buffer, Predicate<E> predicate) {
-+        return PredicatedBuffer.decorate(buffer, predicate);
-+    }
-+
-+    /**
-+     * Returns a typed buffer backed by the given buffer.
-+     * <p/>
-+     * Only elements of the specified type can be added to the buffer.
-+     *
-+     * @param buffer the buffer to predicate, must not be null
-+     * @param type   the type to allow into the buffer, must not be null
-+     * @return a typed buffer
-+     * @throws IllegalArgumentException if the buffer or type is null
-+     * @deprecated No longer required with Java 1.5 Generics.
-+     */
-+    public static <E> Buffer<E> typedBuffer(Buffer<E> buffer, Class<E> type) {
-+        return TypedBuffer.decorate(buffer, type);
-+    }
-+
-+    /**
-+     * Returns a transformed buffer backed by the given buffer.
-+     * <p/>
-+     * Each object is passed through the transformer as it is added to the
-+     * Buffer. It is important not to use the original buffer after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param buffer      the buffer to predicate, must not be null
-+     * @param transformer the transformer for the buffer, must not be null
-+     * @return a transformed buffer backed by the given buffer
-+     * @throws IllegalArgumentException if the Buffer or Transformer is null
-+     */
-+    public static <I,O> Buffer<O> transformedBuffer(Buffer<I> buffer, Transformer<I, O> transformer) {
-+        return TransformedBuffer.decorate(buffer, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/Closure.java
-@@ -0,0 +1,46 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines a functor interface implemented by classes that do something.
-+ * <p/>
-+ * A <code>Closure</code> represents a block of code which is executed from
-+ * inside some block, function or iteration. It operates an input object.
-+ * <p/>
-+ * Standard implementations of common closures are provided by
-+ * {@link ClosureUtils}. These include method invokation and for/while loops.
-+ *
-+ * @author James Strachan
-+ * @author Nicola Ken Barozzi
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public interface Closure <T> {
-+
-+    /**
-+     * Performs an action on the specified input object.
-+     *
-+     * @param input the input to execute on
-+     * @throws ClassCastException       (runtime) if the input is the wrong class
-+     * @throws IllegalArgumentException (runtime) if the input is invalid
-+     * @throws FunctorException         (runtime) if any other error occurs
-+     */
-+    public void execute(T input);
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/ClosureUtils.java
-@@ -0,0 +1,326 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.functors.*;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Map;
-+
-+/**
-+ * <code>ClosureUtils</code> provides reference implementations and utilities
-+ * for the Closure functor interface. The supplied closures are:
-+ * <ul>
-+ * <li>Invoker - invokes a method on the input object
-+ * <li>For - repeatedly calls a closure for a fixed number of times
-+ * <li>While - repeatedly calls a closure while a predicate is true
-+ * <li>DoWhile - repeatedly calls a closure while a predicate is true
-+ * <li>Chained - chains two or more closures together
-+ * <li>Switch - calls one closure based on one or more predicates
-+ * <li>SwitchMap - calls one closure looked up from a Map
-+ * <li>Transformer - wraps a Transformer as a Closure
-+ * <li>NOP - does nothing
-+ * <li>Exception - always throws an exception
-+ * </ul>
-+ * All the supplied closures are Serializable.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ClosureUtils {
-+
-+    /**
-+     * This class is not normally instantiated.
-+     */
-+    public ClosureUtils() {
-+        super();
-+    }
-+
-+    /**
-+     * Gets a Closure that always throws an exception.
-+     * This could be useful during testing as a placeholder.
-+     *
-+     * @return the closure
-+     * @see org.apache.commons.collections15.functors.ExceptionClosure
-+     */
-+    public static Closure exceptionClosure() {
-+        return ExceptionClosure.INSTANCE;
-+    }
-+
-+    /**
-+     * Gets a Closure that will do nothing.
-+     * This could be useful during testing as a placeholder.
-+     *
-+     * @return the closure
-+     * @see org.apache.commons.collections15.functors.NOPClosure
-+     */
-+    public static Closure nopClosure() {
-+        return NOPClosure.INSTANCE;
-+    }
-+
-+    /**
-+     * Creates a Closure that calls a Transformer each time it is called.
-+     * The transformer will be called using the closure's input object.
-+     * The transformer's result will be ignored.
-+     *
-+     * @param transformer the transformer to run each time in the closure, null means nop
-+     * @return the closure
-+     * @see org.apache.commons.collections15.functors.TransformerClosure
-+     */
-+    public static <I,O> Closure<I> asClosure(Transformer<I, O> transformer) {
-+        return TransformerClosure.getInstance(transformer);
-+    }
-+
-+    /**
-+     * Creates a Closure that will call the closure <code>count</code> times.
-+     * <p/>
-+     * A null closure or zero count returns the <code>NOPClosure</code>.
-+     *
-+     * @param count   the number of times to loop
-+     * @param closure the closure to call repeatedly
-+     * @return the <code>for</code> closure
-+     * @see org.apache.commons.collections15.functors.ForClosure
-+     */
-+    public static <T> Closure<T> forClosure(int count, Closure<T> closure) {
-+        return ForClosure.getInstance(count, closure);
-+    }
-+
-+    /**
-+     * Creates a Closure that will call the closure repeatedly until the
-+     * predicate returns false.
-+     *
-+     * @param predicate the predicate to use as an end of loop test, not null
-+     * @param closure   the closure to call repeatedly, not null
-+     * @return the <code>while</code> closure
-+     * @throws IllegalArgumentException if either argument is null
-+     * @see org.apache.commons.collections15.functors.WhileClosure
-+     */
-+    public static <T> Closure<T> whileClosure(Predicate<? super T> predicate, Closure<? super T> closure) {
-+        return WhileClosure.<T>getInstance(predicate, closure, false);
-+    }
-+
-+    /**
-+     * Creates a Closure that will call the closure once and then repeatedly
-+     * until the predicate returns false.
-+     *
-+     * @param closure   the closure to call repeatedly, not null
-+     * @param predicate the predicate to use as an end of loop test, not null
-+     * @return the <code>do-while</code> closure
-+     * @throws IllegalArgumentException if either argument is null
-+     * @see org.apache.commons.collections15.functors.WhileClosure
-+     */
-+    public static <T> Closure<T> doWhileClosure(Closure<? super T> closure, Predicate<? super T> predicate) {
-+        return WhileClosure.<T>getInstance(predicate, closure, true);
-+    }
-+
-+    /**
-+     * Creates a Closure that will invoke a specific method on the closure's
-+     * input object by reflection.
-+     *
-+     * @param methodName the name of the method
-+     * @return the <code>invoker</code> closure
-+     * @throws IllegalArgumentException if the method name is null
-+     * @see org.apache.commons.collections15.functors.InvokerTransformer
-+     * @see org.apache.commons.collections15.functors.TransformerClosure
-+     */
-+    public static Closure invokerClosure(String methodName) {
-+        // reuse transformer as it has caching - this is lazy really, should have inner class here
-+        return asClosure(InvokerTransformer.getInstance(methodName));
-+    }
-+
-+    /**
-+     * Creates a Closure that will invoke a specific method on the closure's
-+     * input object by reflection.
-+     *
-+     * @param methodName the name of the method
-+     * @param paramTypes the parameter types
-+     * @param args       the arguments
-+     * @return the <code>invoker</code> closure
-+     * @throws IllegalArgumentException if the method name is null
-+     * @throws IllegalArgumentException if the paramTypes and args don't match
-+     * @see org.apache.commons.collections15.functors.InvokerTransformer
-+     * @see org.apache.commons.collections15.functors.TransformerClosure
-+     */
-+    public static Closure invokerClosure(String methodName, Class[] paramTypes, Object[] args) {
-+        // reuse transformer as it has caching - this is lazy really, should have inner class here
-+        return asClosure(InvokerTransformer.getInstance(methodName, paramTypes, args));
-+    }
-+
-+    /**
-+     * Create a new Closure that calls two Closures, passing the result of
-+     * the first into the second.
-+     *
-+     * @param closure1 the first closure
-+     * @param closure2 the second closure
-+     * @return the <code>chained</code> closure
-+     * @throws IllegalArgumentException if either closure is null
-+     * @see org.apache.commons.collections15.functors.ChainedClosure
-+     */
-+    public static <T> Closure<T> chainedClosure(Closure<T> closure1, Closure<T> closure2) {
-+        return ChainedClosure.<T>getInstance(closure1, closure2);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls each closure in turn, passing the
-+     * result into the next closure.
-+     *
-+     * @param closures an array of closures to chain
-+     * @return the <code>chained</code> closure
-+     * @throws IllegalArgumentException if the closures array is null
-+     * @throws IllegalArgumentException if any closure in the array is null
-+     * @see org.apache.commons.collections15.functors.ChainedClosure
-+     */
-+    public static <T> Closure<T> chainedClosure(Closure<T>[] closures) {
-+        return ChainedClosure.getInstance(closures);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls each closure in turn, passing the
-+     * result into the next closure. The ordering is that of the iterator()
-+     * method on the collection.
-+     *
-+     * @param closures a collection of closures to chain
-+     * @return the <code>chained</code> closure
-+     * @throws IllegalArgumentException if the closures collection is null
-+     * @throws IllegalArgumentException if the closures collection is empty
-+     * @throws IllegalArgumentException if any closure in the collection is null
-+     * @see org.apache.commons.collections15.functors.ChainedClosure
-+     */
-+    public static <T> Closure<T> chainedClosure(Collection<T> closures) {
-+        return ChainedClosure.getInstance(closures);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls one of two closures depending
-+     * on the specified predicate.
-+     *
-+     * @param predicate    the predicate to switch on
-+     * @param trueClosure  the closure called if the predicate is true
-+     * @param falseClosure the closure called if the predicate is false
-+     * @return the <code>switch</code> closure
-+     * @throws IllegalArgumentException if the predicate is null
-+     * @throws IllegalArgumentException if either closure is null
-+     * @see org.apache.commons.collections15.functors.IfClosure
-+     */
-+    public static <T> Closure<T> ifClosure(Predicate<? super T> predicate, Closure<? super T> trueClosure, Closure<? super T> falseClosure) {
-+        return IfClosure.<T>getInstance(predicate, trueClosure, falseClosure);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls one of the closures depending
-+     * on the predicates.
-+     * <p/>
-+     * The closure at array location 0 is called if the predicate at array
-+     * location 0 returned true. Each predicate is evaluated
-+     * until one returns true.
-+     *
-+     * @param predicates an array of predicates to check, not null
-+     * @param closures   an array of closures to call, not null
-+     * @return the <code>switch</code> closure
-+     * @throws IllegalArgumentException if the either array is null
-+     * @throws IllegalArgumentException if any element in the arrays is null
-+     * @throws IllegalArgumentException if the arrays are different sizes
-+     * @see org.apache.commons.collections15.functors.SwitchClosure
-+     */
-+    public static <T> Closure<T> switchClosure(Predicate<? super T>[] predicates, Closure<? super T>[] closures) {
-+        return SwitchClosure.<T>getInstance(predicates, closures, null);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls one of the closures depending
-+     * on the predicates.
-+     * <p/>
-+     * The closure at array location 0 is called if the predicate at array
-+     * location 0 returned true. Each predicate is evaluated
-+     * until one returns true. If no predicates evaluate to true, the default
-+     * closure is called.
-+     *
-+     * @param predicates     an array of predicates to check, not null
-+     * @param closures       an array of closures to call, not null
-+     * @param defaultClosure the default to call if no predicate matches
-+     * @return the <code>switch</code> closure
-+     * @throws IllegalArgumentException if the either array is null
-+     * @throws IllegalArgumentException if any element in the arrays is null
-+     * @throws IllegalArgumentException if the arrays are different sizes
-+     * @see org.apache.commons.collections15.functors.SwitchClosure
-+     */
-+    public static <T> Closure<T> switchClosure(Predicate<? super T>[] predicates, Closure<? super T>[] closures, Closure<? super T> defaultClosure) {
-+        return SwitchClosure.<T>getInstance(predicates, closures, defaultClosure);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls one of the closures depending
-+     * on the predicates.
-+     * <p/>
-+     * The Map consists of Predicate keys and Closure values. A closure
-+     * is called if its matching predicate returns true. Each predicate is evaluated
-+     * until one returns true. If no predicates evaluate to true, the default
-+     * closure is called. The default closure is set in the map with a
-+     * null key. The ordering is that of the iterator() method on the entryset
-+     * collection of the map.
-+     *
-+     * @param predicatesAndClosures a map of predicates to closures
-+     * @return the <code>switch</code> closure
-+     * @throws IllegalArgumentException if the map is null
-+     * @throws IllegalArgumentException if the map is empty
-+     * @throws IllegalArgumentException if any closure in the map is null
-+     * @throws ClassCastException       if the map elements are of the wrong type
-+     * @see org.apache.commons.collections15.functors.SwitchClosure
-+     */
-+    public static <T> Closure<T> switchClosure(Map<Predicate<? super T>, Closure<? super T>> predicatesAndClosures) {
-+        return SwitchClosure.<T>getInstance(predicatesAndClosures);
-+    }
-+
-+    /**
-+     * Create a new Closure that uses the input object as a key to find the
-+     * closure to call.
-+     * <p/>
-+     * The Map consists of object keys and Closure values. A closure
-+     * is called if the input object equals the key. If there is no match, the
-+     * default closure is called. The default closure is set in the map
-+     * using a null key.
-+     *
-+     * @param objectsAndClosures a map of objects to closures
-+     * @return the closure
-+     * @throws IllegalArgumentException if the map is null
-+     * @throws IllegalArgumentException if the map is empty
-+     * @throws IllegalArgumentException if any closure in the map is null
-+     * @see org.apache.commons.collections15.functors.SwitchClosure
-+     */
-+    public static <T> Closure<T> switchMapClosure(Map<T, Closure<T>> objectsAndClosures) {
-+        Closure[] trs = null;
-+        Predicate[] preds = null;
-+        if (objectsAndClosures == null) {
-+            throw new IllegalArgumentException("The object and closure map must not be null");
-+        }
-+        Closure def = (Closure) objectsAndClosures.remove(null);
-+        int size = objectsAndClosures.size();
-+        trs = new Closure[size];
-+        preds = new Predicate[size];
-+        int i = 0;
-+        for (Iterator it = objectsAndClosures.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            preds[i] = EqualPredicate.getInstance(entry.getKey());
-+            trs[i] = (Closure) entry.getValue();
-+            i++;
-+        }
-+        return switchClosure(preds, trs, def);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/CollectionUtils.java
-@@ -0,0 +1,1072 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.collection.*;
-+
-+import java.lang.reflect.Array;
-+import java.util.*;
-+
-+/**
-+ * Provides utility methods and decorators for {@link Collection} instances.
-+ *
-+ * @author Rodney Waldhoff
-+ * @author Paul Jack
-+ * @author Stephen Colebourne
-+ * @author Steve Downey
-+ * @author Herve Quiroz
-+ * @author Peter KoBek
-+ * @author Matthew Hawthorne
-+ * @author Janek Bogucki
-+ * @author Phil Steitz
-+ * @author Steven Melzer
-+ * @author Matt Hall, John Watkinson, Jon Schewe
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public class CollectionUtils {
-+
-+    /**
-+     * Constant to avoid repeated object creation
-+     */
-+    private static Integer INTEGER_ONE = new Integer(1);
-+
-+    /**
-+     * An empty unmodifiable collection.
-+     * The JDK provides empty Set and List implementations which could be used for
-+     * this purpose. However they could be cast to Set or List which might be
-+     * undesirable. This implementation only implements Collection.
-+     */
-+    public static final Collection EMPTY_COLLECTION = UnmodifiableCollection.decorate(new ArrayList());
-+
-+    /**
-+     * <code>CollectionUtils</code> should not normally be instantiated.
-+     */
-+    public CollectionUtils() {
-+    }
-+
-+    /**
-+     * Returns a {@link Collection} containing the union
-+     * of the given {@link Collection}s.
-+     * <p/>
-+     * The cardinality of each element in the returned {@link Collection}
-+     * will be equal to the maximum of the cardinality of that element
-+     * in the two given {@link Collection}s.
-+     *
-+     * @param a the first collection, must not be null
-+     * @param b the second collection, must not be null
-+     * @return the union of the two collections15
-+     * @see Collection#addAll
-+     */
-+    public static <E> Collection<E> union(final Collection<? extends E> a, final Collection<? extends E> b) {
-+        ArrayList<E> list = new ArrayList<E>();
-+        Map mapa = getCardinalityMap(a);
-+        Map mapb = getCardinalityMap(b);
-+        Set<E> elts = new HashSet<E>(a);
-+        elts.addAll(b);
-+        Iterator<E> it = elts.iterator();
-+        while (it.hasNext()) {
-+            E obj = it.next();
-+            for (int i = 0, m = Math.max(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; i++) {
-+                list.add(obj);
-+            }
-+        }
-+        return list;
-+    }
-+
-+    /**
-+     * Returns a {@link Collection} containing the intersection
-+     * of the given {@link Collection}s.
-+     * <p/>
-+     * The cardinality of each element in the returned {@link Collection}
-+     * will be equal to the minimum of the cardinality of that element
-+     * in the two given {@link Collection}s.
-+     *
-+     * @param a the first collection, must not be null
-+     * @param b the second collection, must not be null
-+     * @return the intersection of the two collections15
-+     * @see Collection#retainAll
-+     * @see #containsAny
-+     */
-+    public static <E> Collection<E> intersection(final Collection<? extends E> a, final Collection<? extends E> b) {
-+        ArrayList<E> list = new ArrayList<E>();
-+        Map mapa = getCardinalityMap(a);
-+        Map mapb = getCardinalityMap(b);
-+        Set<E> elts = new HashSet<E>(a);
-+        elts.addAll(b);
-+        Iterator<E> it = elts.iterator();
-+        while (it.hasNext()) {
-+            E obj = it.next();
-+            for (int i = 0, m = Math.min(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; i++) {
-+                list.add(obj);
-+            }
-+        }
-+        return list;
-+    }
-+
-+    /**
-+     * Returns a {@link Collection} containing the exclusive disjunction
-+     * (symmetric difference) of the given {@link Collection}s.
-+     * <p/>
-+     * The cardinality of each element <i>e</i> in the returned {@link Collection}
-+     * will be equal to
-+     * <tt>max(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>)) - min(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>))</tt>.
-+     * <p/>
-+     * This is equivalent to
-+     * <tt>{@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)})</tt>
-+     * or
-+     * <tt>{@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)})</tt>.
-+     *
-+     * @param a the first collection, must not be null
-+     * @param b the second collection, must not be null
-+     * @return the symmetric difference of the two collections15
-+     */
-+    public static <E> Collection<E> disjunction(final Collection<E> a, final Collection<E> b) {
-+        ArrayList<E> list = new ArrayList<E>();
-+        Map mapa = getCardinalityMap(a);
-+        Map mapb = getCardinalityMap(b);
-+        Set<E> elts = new HashSet<E>(a);
-+        elts.addAll(b);
-+        Iterator<E> it = elts.iterator();
-+        while (it.hasNext()) {
-+            E obj = it.next();
-+            for (int i = 0, m = ((Math.max(getFreq(obj, mapa), getFreq(obj, mapb))) - (Math.min(getFreq(obj, mapa), getFreq(obj, mapb)))); i < m; i++) {
-+                list.add(obj);
-+            }
-+        }
-+        return list;
-+    }
-+
-+    /**
-+     * Returns a new {@link Collection} containing <tt><i>a</i> - <i>b</i></tt>.
-+     * The cardinality of each element <i>e</i> in the returned {@link Collection}
-+     * will be the cardinality of <i>e</i> in <i>a</i> minus the cardinality
-+     * of <i>e</i> in <i>b</i>, or zero, whichever is greater.
-+     *
-+     * @param a the collection to subtract from, must not be null
-+     * @param b the {@link Iterable} to subtract, must not be null
-+     * @return a new collection with the results
-+     * @see Collection#removeAll
-+     */
-+    public static <E> Collection<E> subtract(final Collection<? extends E> a, final Iterable<? extends E> b) {
-+        ArrayList<E> list = new ArrayList<E>(a);
-+        for (E e : b) {
-+            list.remove(e);
-+        }
-+        return list;
-+    }
-+
-+    /**
-+     * Returns <code>true</code> iff at least one element is in both collections15.
-+     * <p/>
-+     * In other words, this method returns <code>true</code> iff the
-+     * {@link #intersection} of <i>coll1</i> and <i>coll2</i> is not empty.
-+     *
-+     * @param coll1 the first collection, must not be null
-+     * @param coll2 the first collection, must not be null
-+     * @return <code>true</code> iff the intersection of the collections15 is non-empty
-+     * @see #intersection
-+     * @since 2.1
-+     */
-+    public static <E> boolean containsAny(final Collection<? extends E> coll1, final Collection<? extends E> coll2) {
-+        if (coll1.size() < coll2.size()) {
-+            for (Iterator it = coll1.iterator(); it.hasNext();) {
-+                if (coll2.contains(it.next())) {
-+                    return true;
-+                }
-+            }
-+        } else {
-+            for (Iterator it = coll2.iterator(); it.hasNext();) {
-+                if (coll1.contains(it.next())) {
-+                    return true;
-+                }
-+            }
-+        }
-+        return false;
-+    }
-+
-+    public static void main(String[] args) {
-+        List<String> l1 = new ArrayList<String>();
-+        l1.add("Test");
-+        List<Integer> l2 = new ArrayList<Integer>();
-+        l2.add(1);
-+        containsAny(l1, l2);
-+    }
-+
-+    /**
-+     * Returns a {@link Map} mapping each unique element in the given
-+     * {@link Iterable} to an {@link Integer} representing the number
-+     * of occurrences of that element in the {@link Iterable}.
-+     * <p/>
-+     * Only those elements present in the Iterable will appear as
-+     * keys in the map.
-+     *
-+     * @param iterable the collection to get the cardinality map for, must not be null
-+     * @return the populated cardinality map
-+     */
-+    public static <E> Map<E, java.lang.Integer> getCardinalityMap(final Iterable<E> iterable) {
-+        Map<E, Integer> count = new HashMap<E, Integer>();
-+        for (Iterator<E> it = iterable.iterator(); it.hasNext();) {
-+            E obj = it.next();
-+            Integer c = count.get(obj);
-+            if (c == null) {
-+                count.put(obj, INTEGER_ONE);
-+            } else {
-+                count.put(obj, new Integer(c.intValue() + 1));
-+            }
-+        }
-+        return count;
-+    }
-+
-+    /**
-+     * Returns <tt>true</tt> iff <i>a</i> is a sub-collection of <i>b</i>,
-+     * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
-+     * than or equal to the cardinality of <i>e</i> in <i>b</i>,
-+     * for each element <i>e</i> in <i>a</i>.
-+     *
-+     * @param a the first (sub?) collection, must not be null
-+     * @param b the second (super?) collection, must not be null
-+     * @return <code>true</code> iff <i>a</i> is a sub-collection of <i>b</i>
-+     * @see #isProperSubCollection
-+     * @see Collection#containsAll
-+     */
-+    public static <E> boolean isSubCollection(final Iterable<? extends E> a, final Iterable<? extends E> b) {
-+        Map mapa = getCardinalityMap(a);
-+        Map mapb = getCardinalityMap(b);
-+        for (E obj : a) {
-+            if (getFreq(obj, mapa) > getFreq(obj, mapb)) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Returns <tt>true</tt> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>,
-+     * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
-+     * than or equal to the cardinality of <i>e</i> in <i>b</i>,
-+     * for each element <i>e</i> in <i>a</i>, and there is at least one
-+     * element <i>f</i> such that the cardinality of <i>f</i> in <i>b</i>
-+     * is strictly greater than the cardinality of <i>f</i> in <i>a</i>.
-+     * <p/>
-+     * The implementation assumes
-+     * <ul>
-+     * <li><code>a.size()</code> and <code>b.size()</code> represent the
-+     * total cardinality of <i>a</i> and <i>b</i>, resp. </li>
-+     * <li><code>a.size() < Integer.MAXVALUE</code></li>
-+     * </ul>
-+     *
-+     * @param a the first (sub?) collection, must not be null
-+     * @param b the second (super?) collection, must not be null
-+     * @return <code>true</code> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>
-+     * @see #isSubCollection
-+     * @see Collection#containsAll
-+     */
-+    public static <E> boolean isProperSubCollection(final Collection<? extends E> a, final Collection<? extends E> b) {
-+        return (a.size() < b.size()) && CollectionUtils.isSubCollection(a, b);
-+    }
-+
-+    /**
-+     * Returns <tt>true</tt> iff the given {@link Collection}s contain
-+     * exactly the same elements with exactly the same cardinalities.
-+     * <p/>
-+     * That is, iff the cardinality of <i>e</i> in <i>a</i> is
-+     * equal to the cardinality of <i>e</i> in <i>b</i>,
-+     * for each element <i>e</i> in <i>a</i> or <i>b</i>.
-+     *
-+     * @param a the first collection, must not be null
-+     * @param b the second collection, must not be null
-+     * @return <code>true</code> iff the collections15 contain the same elements with the same cardinalities.
-+     */
-+    public static <E> boolean isEqualCollection(final Collection<? extends E> a, final Collection<? extends E> b) {
-+        if (a.size() != b.size()) {
-+            return false;
-+        } else {
-+            Map mapa = getCardinalityMap(a);
-+            Map mapb = getCardinalityMap(b);
-+            if (mapa.size() != mapb.size()) {
-+                return false;
-+            } else {
-+                Iterator it = mapa.keySet().iterator();
-+                while (it.hasNext()) {
-+                    Object obj = it.next();
-+                    if (getFreq(obj, mapa) != getFreq(obj, mapb)) {
-+                        return false;
-+                    }
-+                }
-+                return true;
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Returns the number of occurrences of <i>obj</i> in <i>coll</i>.
-+     *
-+     * @param obj  the object to find the cardinality of
-+     * @param coll the collection to search
-+     * @return the the number of occurrences of obj in coll
-+     */
-+    public static <E> int cardinality(E obj, final Collection<? super E> coll) {
-+        if (coll instanceof Set) {
-+            return (coll.contains(obj) ? 1 : 0);
-+        }
-+        if (coll instanceof Bag) {
-+            return ((Bag) coll).getCount(obj);
-+        }
-+        int count = 0;
-+        if (obj == null) {
-+            for (Iterator it = coll.iterator(); it.hasNext();) {
-+                if (it.next() == null) {
-+                    count++;
-+                }
-+            }
-+        } else {
-+            for (Iterator it = coll.iterator(); it.hasNext();) {
-+                if (obj.equals(it.next())) {
-+                    count++;
-+                }
-+            }
-+        }
-+        return count;
-+    }
-+
-+    /**
-+     * Finds the first element in the given iterable which matches the given predicate.
-+     * <p/>
-+     * If the input iterable or predicate is null, or no element of the iterable
-+     * matches the predicate, null is returned.
-+     *
-+     * @param iterable the iterable to search, may be null
-+     * @param predicate  the predicate to use, may be null
-+     * @return the first element of the iterable which matches the predicate or null if none could be found
-+     */
-+    public static <E> E find(Iterable<E> iterable, Predicate<? super E> predicate) {
-+        if (iterable != null && predicate != null) {
-+            for (Iterator<E> iter = iterable.iterator(); iter.hasNext();) {
-+                E item = iter.next();
-+                if (predicate.evaluate(item)) {
-+                    return item;
-+                }
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Executes the given closure on each element in the iterable.
-+     * <p/>
-+     * If the input iterable or closure is null, there is no change made.
-+     *
-+     * @param iterable the iterable to get the input from, may be null
-+     * @param closure    the closure to perform, may be null
-+     */
-+    public static <E> void forAllDo(Iterable<E> iterable, Closure<? super E> closure) {
-+        if (iterable != null && closure != null) {
-+            for (Iterator<E> it = iterable.iterator(); it.hasNext();) {
-+                closure.execute(it.next());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Filter the iterable by applying a Predicate to each element. If the
-+     * predicate returns false, remove the element.
-+     * <p/>
-+     * If the input iterable or predicate is null, there is no change made.
-+     *
-+     * @param iterable the iterable to get the input from, may be null
-+     * @param predicate  the predicate to use as a filter, may be null
-+     */
-+    public static <E> void filter(Iterable<E> iterable, Predicate<? super E> predicate) {
-+        if (iterable != null && predicate != null) {
-+            for (Iterator<E> it = iterable.iterator(); it.hasNext();) {
-+                if (predicate.evaluate(it.next()) == false) {
-+                    it.remove();
-+                }
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Transform the collection by applying a Transformer to each element.
-+     * <p/>
-+     * If the input collection or transformer is null, there is no change made.
-+     * <p/>
-+     * This routine is best for Lists, for which set() is used to do the
-+     * transformations "in place."  For other Collections, clear() and addAll()
-+     * are used to replace elements.
-+     * <p/>
-+     * If the input collection controls its input, such as a Set, and the
-+     * Transformer creates duplicates (or are otherwise invalid), the
-+     * collection may reduce in size due to calling this method.
-+     *
-+     * @param collection  the collection to get the input from, may be null
-+     * @param transformer the transformer to perform, may be null
-+     */
-+    public static <E> void transform(Collection<E> collection, Transformer<? super E, ? extends E> transformer) {
-+        if (collection != null && transformer != null) {
-+            if (collection instanceof List) {
-+                List<E> list = (List<E>) collection;
-+                for (ListIterator<E> it = list.listIterator(); it.hasNext();) {
-+                    it.set(transformer.transform(it.next()));
-+                }
-+            } else {
-+                Collection<E> resultCollection = collect(collection, transformer);
-+                collection.clear();
-+                collection.addAll(resultCollection);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Counts the number of elements in the input collection that match the predicate.
-+     * <p/>
-+     * A <code>null</code> collection or predicate matches no elements.
-+     *
-+     * @param inputIterable the collection to get the input from, may be null
-+     * @param predicate       the predicate to use, may be null
-+     * @return the number of matches for the predicate in the collection
-+     */
-+    public static <E> int countMatches(Iterable<E> inputIterable, Predicate<? super E> predicate) {
-+        int count = 0;
-+        if (inputIterable != null && predicate != null) {
-+            for (Iterator<E> it = inputIterable.iterator(); it.hasNext();) {
-+                if (predicate.evaluate(it.next())) {
-+                    count++;
-+                }
-+            }
-+        }
-+        return count;
-+    }
-+
-+    /**
-+     * Answers true if a predicate is true for at least one element of a iterable.
-+     * <p/>
-+     * A <code>null</code> iterable or predicate returns false.
-+     *
-+     * @param iterable the iterable to get the input from, may be null
-+     * @param predicate  the predicate to use, may be null
-+     * @return true if at least one element of the iterable matches the predicate
-+     */
-+    public static <E> boolean exists(Iterable<E> iterable, Predicate<? super E> predicate) {
-+        if (iterable != null && predicate != null) {
-+            for (Iterator<E> it = iterable.iterator(); it.hasNext();) {
-+                if (predicate.evaluate(it.next())) {
-+                    return true;
-+                }
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Selects all elements from input collection which match the given predicate
-+     * into an output collection.
-+     * <p/>
-+     * A <code>null</code> predicate matches no elements.
-+     *
-+     * @param inputCollection the collection to get the input from, may not be null
-+     * @param predicate       the predicate to use, may be null
-+     * @return the elements matching the predicate (new list)
-+     * @throws NullPointerException if the input collection is null
-+     */
-+    public static <E> Collection<E> select(Collection<E> inputCollection, Predicate<? super E> predicate) {
-+        return select(inputCollection, predicate, new ArrayList<E>(inputCollection.size()));
-+    }
-+
-+    /**
-+     * Selects all elements from input collection which match the given predicate
-+     * and adds them to outputCollection.
-+     * <p/>
-+     * If the input collection or predicate is null, there is no change to the
-+     * output collection.
-+     *
-+     * @param inputCollection  the collection to get the input from, may be null
-+     * @param predicate        the predicate to use, may be null
-+     * @param outputCollection the collection to output into, may not be null
-+     */
-+    public static <E, C extends Collection<? super E>> C select(Iterable<E> inputCollection, Predicate<? super E> predicate, C outputCollection) {
-+        if (inputCollection != null && predicate != null) {
-+            for (Iterator<E> iter = inputCollection.iterator(); iter.hasNext();) {
-+                E item = iter.next();
-+                if (predicate.evaluate(item)) {
-+                    outputCollection.add(item);
-+                }
-+            }
-+        }
-+        return outputCollection;
-+    }
-+
-+    /**
-+     * Selects all elements from inputCollection which don't match the given predicate
-+     * into an output collection.
-+     * <p/>
-+     * If the input predicate is <code>null</code>, the result is an empty list.
-+     *
-+     * @param inputCollection the collection to get the input from, may not be null
-+     * @param predicate       the predicate to use, may be null
-+     * @return the elements <b>not</b> matching the predicate (new list)
-+     * @throws NullPointerException if the input collection is null
-+     */
-+    public static <E> Collection<E> selectRejected(Collection<E> inputCollection, Predicate<? super E> predicate) {
-+        ArrayList<E> answer = new ArrayList<E>(inputCollection.size());
-+        selectRejected(inputCollection, predicate, answer);
-+        return answer;
-+    }
-+
-+    /**
-+     * Selects all elements from inputIterable which don't match the given predicate
-+     * and adds them to outputCollection.
-+     * <p/>
-+     * If the input predicate is <code>null</code>, no elements are added to <code>outputCollection</code>.
-+     *
-+     * @param inputIterable  the collection to get the input from, may be null
-+     * @param predicate        the predicate to use, may be null
-+     * @param outputCollection the collection to output into, may not be null
-+     */
-+    public static <E> void selectRejected(Iterable<E> inputIterable, Predicate<? super E> predicate, Collection<? super E> outputCollection) {
-+        if (inputIterable != null && predicate != null) {
-+            for (Iterator<E> iter = inputIterable.iterator(); iter.hasNext();) {
-+                E item = iter.next();
-+                if (predicate.evaluate(item) == false) {
-+                    outputCollection.add(item);
-+                }
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Returns a new Collection consisting of the elements of inputCollection transformed
-+     * by the given transformer.
-+     * <p/>
-+     * If the input transformer is null, the result is an empty list.
-+     *
-+     * @param inputCollection the collection to get the input from, may not be null
-+     * @param transformer     the transformer to use, may be null
-+     * @return the transformed result (new list)
-+     * @throws NullPointerException if the input collection is null
-+     */
-+    public static <I,O> Collection<O> collect(Collection<I> inputCollection, Transformer<? super I, ? extends O> transformer) {
-+        ArrayList<O> answer = new ArrayList<O>(inputCollection.size());
-+        collect(inputCollection, transformer, answer);
-+        return answer;
-+    }
-+
-+    /**
-+     * Transforms all elements from the inputIterator with the given transformer
-+     * and adds them to the outputCollection.
-+     * <p/>
-+     * If the input iterator or transformer is null, the result is an empty list.
-+     *
-+     * @param inputIterator the iterator to get the input from, may be null
-+     * @param transformer   the transformer to use, may be null
-+     * @return the transformed result (new list)
-+     */
-+    public static <I,O> Collection<O> collect(Iterator<I> inputIterator, Transformer<? super I, ? extends O> transformer) {
-+        ArrayList<O> answer = new ArrayList<O>();
-+        collect(inputIterator, transformer, answer);
-+        return answer;
-+    }
-+
-+    /**
-+     * Transforms all elements from inputCollection with the given transformer
-+     * and adds them to the outputCollection.
-+     * <p/>
-+     * If the input collection or transformer is null, there is no change to the
-+     * output collection.
-+     *
-+     * @param inputCollection  the collection to get the input from, may be null
-+     * @param transformer      the transformer to use, may not be null
-+     * @param outputCollection the collection to output into, may not be null
-+     * @return the outputCollection with the transformed input added
-+     * @throws NullPointerException if the output collection is null
-+     */
-+    public static <I,O,C extends Collection<O>> C collect(Iterable<I> inputCollection, final Transformer<? super I, ? extends O> transformer, final C outputCollection) {
-+        if (inputCollection != null) {
-+            return collect(inputCollection.iterator(), transformer, outputCollection);
-+        }
-+        return outputCollection;
-+    }
-+
-+    /**
-+     * Transforms all elements from the inputIterator with the given transformer
-+     * and adds them to the outputCollection.
-+     * <p/>
-+     * If the input iterator or transformer is null, there is no change to the
-+     * output collection.
-+     *
-+     * @param inputIterator    the iterator to get the input from, may be null
-+     * @param transformer      the transformer to use, may not be null
-+     * @param outputCollection the collection to output into, may not be null
-+     * @return the outputCollection with the transformed input added
-+     * @throws NullPointerException if the output collection is null
-+     */
-+    public static <I,O,C extends Collection<O>> C collect(Iterator<I> inputIterator, final Transformer<? super I, ? extends O> transformer, final C outputCollection) {
-+        if (inputIterator != null && transformer != null) {
-+            while (inputIterator.hasNext()) {
-+                I item = inputIterator.next();
-+                O value = transformer.transform(item);
-+                outputCollection.add(value);
-+            }
-+        }
-+        return outputCollection;
-+    }
-+
-+    /**
-+     * Adds all elements in the iteration to the given collection.
-+     * @deprecated Replaced by {@link Collection#addAll(java.util.Collection<? extends E>)}
-+     *
-+     * @param collection the collection to add to
-+     * @param iterator   the iterator of elements to add, may not be null
-+     * @throws NullPointerException if the collection or iterator is null
-+     */
-+    public static <E> void addAll(Collection<E> collection, Iterator<? extends E> iterator) {
-+        while (iterator.hasNext()) {
-+            collection.add(iterator.next());
-+        }
-+    }
-+
-+    /**
-+     * Adds all elements in the enumeration to the given collection.
-+     * @deprecated Replaced by {@link Collection#addAll(java.util.Collection<? extends E>)}
-+     *
-+     * @param collection  the collection to add to
-+     * @param enumeration the enumeration of elements to add, may not be null
-+     * @throws NullPointerException if the collection or enumeration is null
-+     */
-+    public static <E> void addAll(Collection<E> collection, Enumeration<? extends E> enumeration) {
-+        while (enumeration.hasMoreElements()) {
-+            collection.add(enumeration.nextElement());
-+        }
-+    }
-+
-+    /**
-+     * Adds all elements in the array to the given collection.
-+     *
-+     * @param collection the collection to add to, may not be null
-+     * @param elements   the array of elements to add, may not be null
-+     * @throws NullPointerException if the collection or array is null
-+     */
-+    public static <E, T extends E> void addAll(Collection<E> collection, T... elements) {
-+        for (int i = 0, size = elements.length; i < size; i++) {
-+            collection.add(elements[i]);
-+        }
-+    }
-+
-+    /**
-+     * Given an Object, and an index, returns the nth value in the
-+     * object.
-+     * <ul>
-+     * <li>If obj is a Map, returns the nth value from the <b>keySet</b> iterator, unless
-+     * the Map contains an Integer key with integer value = idx, in which case the
-+     * corresponding map entry value is returned.  If idx exceeds the number of entries in
-+     * the map, an empty Iterator is returned.
-+     * <li>If obj is a List or an array, returns the nth value, throwing IndexOutOfBoundsException,
-+     * ArrayIndexOutOfBoundsException, resp. if the nth value does not exist.
-+     * <li>If obj is an iterator, enumeration or Collection, returns the nth value from the iterator,
-+     * returning an empty Iterator (resp. Enumeration) if the nth value does not exist.
-+     * <li>Returns the original obj if it is null or not a Collection or Iterator.
-+     * </ul>
-+     *
-+     * @param obj the object to get an index of, may be null
-+     * @param idx the index to get
-+     * @throws IndexOutOfBoundsException
-+     * @throws ArrayIndexOutOfBoundsException
-+     * @deprecated use {@link #get(Object, int)} instead. Will be removed in v4.0
-+     */
-+    public static Object index(Object obj, int idx) {
-+        return index(obj, new Integer(idx));
-+    }
-+
-+    /**
-+     * Given an Object, and a key (index), returns the value associated with
-+     * that key in the Object. The following checks are made:
-+     * <ul>
-+     * <li>If obj is a Map, use the index as a key to get a value. If no match continue.
-+     * <li>Check key is an Integer. If not, return the object passed in.
-+     * <li>If obj is a Map, get the nth value from the <b>keySet</b> iterator.
-+     * If the Map has fewer than n entries, return an empty Iterator.
-+     * <li>If obj is a List or an array, get the nth value, throwing IndexOutOfBoundsException,
-+     * ArrayIndexOutOfBoundsException, resp. if the nth value does not exist.
-+     * <li>If obj is an iterator, enumeration or Collection, get the nth value from the iterator,
-+     * returning an empty Iterator (resp. Enumeration) if the nth value does not exist.
-+     * <li>Return the original obj.
-+     * </ul>
-+     *
-+     * @param obj   the object to get an index of
-+     * @param index the index to get
-+     * @return the object at the specified index
-+     * @throws IndexOutOfBoundsException
-+     * @throws ArrayIndexOutOfBoundsException
-+     * @deprecated use {@link #get(Object, int)} instead. Will be removed in v4.0
-+     */
-+    public static Object index(Object obj, Object index) {
-+        if (obj instanceof Map) {
-+            Map map = (Map) obj;
-+            if (map.containsKey(index)) {
-+                return map.get(index);
-+            }
-+        }
-+        int idx = -1;
-+        if (index instanceof Integer) {
-+            idx = ((Integer) index).intValue();
-+        }
-+        if (idx < 0) {
-+            return obj;
-+        } else if (obj instanceof Map) {
-+            Map map = (Map) obj;
-+            Iterator iterator = map.keySet().iterator();
-+            return index(iterator, idx);
-+        } else if (obj instanceof List) {
-+            return ((List) obj).get(idx);
-+        } else if (obj instanceof Object[]) {
-+            return ((Object[]) obj)[idx];
-+        } else if (obj instanceof Enumeration) {
-+            Enumeration it = (Enumeration) obj;
-+            while (it.hasMoreElements()) {
-+                idx--;
-+                if (idx == -1) {
-+                    return it.nextElement();
-+                } else {
-+                    it.nextElement();
-+                }
-+            }
-+        } else if (obj instanceof Iterator) {
-+            return index((Iterator) obj, idx);
-+        } else if (obj instanceof Collection) {
-+            Iterator iterator = ((Collection) obj).iterator();
-+            return index(iterator, idx);
-+        }
-+        return obj;
-+    }
-+
-+    private static Object index(Iterator iterator, int idx) {
-+        while (iterator.hasNext()) {
-+            idx--;
-+            if (idx == -1) {
-+                return iterator.next();
-+            } else {
-+                iterator.next();
-+            }
-+        }
-+        return iterator;
-+    }
-+
-+    /**
-+     * Returns the <code>index</code>-th value in <code>object</code>, throwing
-+     * <code>IndexOutOfBoundsException</code> if there is no such element or
-+     * <code>IllegalArgumentException</code> if <code>object</code> is not an
-+     * instance of one of the supported types.
-+     * <p/>
-+     * The supported types, and associated semantics are:
-+     * <ul>
-+     * <li> Map -- the value returned is the <code>Map.Entry</code> in position
-+     * <code>index</code> in the map's <code>entrySet</code> iterator,
-+     * if there is such an entry.</li>
-+     * <li> List -- this method is equivalent to the list's get method.</li>
-+     * <li> Array -- the <code>index</code>-th array entry is returned,
-+     * if there is such an entry; otherwise an <code>IndexOutOfBoundsException</code>
-+     * is thrown.</li>
-+     * <li> Collection -- the value returned is the <code>index</code>-th object
-+     * returned by the collection's default iterator, if there is such an element.</li>
-+     * <li> Iterator or Enumeration -- the value returned is the
-+     * <code>index</code>-th object in the Iterator/Enumeration, if there
-+     * is such an element.  The Iterator/Enumeration is advanced to
-+     * <code>index</code> (or to the end, if <code>index</code> exceeds the
-+     * number of entries) as a side effect of this method.</li>
-+     * </ul>
-+     *
-+     * @param object the object to get a value from
-+     * @param index  the index to get
-+     * @return the object at the specified index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     * @throws IllegalArgumentException  if the object type is invalid
-+     */
-+    public static Object get(Object object, int index) {
-+        if (index < 0) {
-+            throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
-+        }
-+        if (object instanceof Map) {
-+            Map map = (Map) object;
-+            Iterator iterator = map.entrySet().iterator();
-+            return get(iterator, index);
-+        } else if (object instanceof List) {
-+            return ((List) object).get(index);
-+        } else if (object instanceof Object[]) {
-+            return ((Object[]) object)[index];
-+        } else if (object instanceof Iterator) {
-+            Iterator it = (Iterator) object;
-+            while (it.hasNext()) {
-+                index--;
-+                if (index == -1) {
-+                    return it.next();
-+                } else {
-+                    it.next();
-+                }
-+            }
-+            throw new IndexOutOfBoundsException("Entry does not exist: " + index);
-+        } else if (object instanceof Collection) {
-+            Iterator iterator = ((Collection) object).iterator();
-+            return get(iterator, index);
-+        } else if (object instanceof Enumeration) {
-+            Enumeration it = (Enumeration) object;
-+            while (it.hasMoreElements()) {
-+                index--;
-+                if (index == -1) {
-+                    return it.nextElement();
-+                } else {
-+                    it.nextElement();
-+                }
-+            }
-+            throw new IndexOutOfBoundsException("Entry does not exist: " + index);
-+        } else if (object == null) {
-+            throw new IllegalArgumentException("Unsupported object type: null");
-+        } else {
-+            try {
-+                return Array.get(object, index);
-+            } catch (IllegalArgumentException ex) {
-+                throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Gets the size of the collection/iterator specified.
-+     * <p/>
-+     * This method can handles objects as follows
-+     * <ul>
-+     * <li>Collection - the collection size
-+     * <li>Map - the map size
-+     * <li>Array - the array size
-+     * <li>Iterator - the number of elements remaining in the iterator
-+     * <li>Enumeration - the number of elements remaining in the enumeration
-+     * </ul>
-+     *
-+     * @param object the object to get the size of
-+     * @return the size of the specified collection
-+     * @throws IllegalArgumentException thrown if object is not recognised or null
-+     * @since Commons Collections 3.1
-+     */
-+    public static int size(Object object) {
-+        int total = 0;
-+        if (object instanceof Map) {
-+            total = ((Map) object).size();
-+        } else if (object instanceof Collection) {
-+            total = ((Collection) object).size();
-+        } else if (object instanceof Object[]) {
-+            total = ((Object[]) object).length;
-+        } else if (object instanceof Iterator) {
-+            Iterator it = (Iterator) object;
-+            while (it.hasNext()) {
-+                total++;
-+                it.next();
-+            }
-+        } else if (object instanceof Enumeration) {
-+            Enumeration it = (Enumeration) object;
-+            while (it.hasMoreElements()) {
-+                total++;
-+                it.nextElement();
-+            }
-+        } else if (object == null) {
-+            throw new IllegalArgumentException("Unsupported object type: null");
-+        } else {
-+            try {
-+                total = Array.getLength(object);
-+            } catch (IllegalArgumentException ex) {
-+                throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
-+            }
-+        }
-+        return total;
-+    }
-+
-+    /**
-+     * Reverses the order of the given array.
-+     *
-+     * @param array the array to reverse
-+     */
-+    public static void reverseArray(Object[] array) {
-+        int i = 0;
-+        int j = array.length - 1;
-+        Object tmp;
-+
-+        while (j > i) {
-+            tmp = array[j];
-+            array[j] = array[i];
-+            array[i] = tmp;
-+            j--;
-+            i++;
-+        }
-+    }
-+
-+    private static final int getFreq(final Object obj, final Map freqMap) {
-+        Integer count = (Integer) freqMap.get(obj);
-+        if (count != null) {
-+            return count.intValue();
-+        }
-+        return 0;
-+    }
-+
-+    /**
-+     * Returns true if no more elements can be added to the Collection.
-+     * <p/>
-+     * This method uses the {@link BoundedCollection} interface to determine the
-+     * full status. If the collection does not implement this interface then
-+     * false is returned.
-+     * <p/>
-+     * The collection does not have to implement this interface directly.
-+     * If the collection has been decorated using the decorators subpackage
-+     * then these will be removed to access the BoundedCollection.
-+     *
-+     * @param coll the collection to check
-+     * @return true if the BoundedCollection is full
-+     * @throws NullPointerException if the collection is null
-+     */
-+    public static boolean isFull(Collection coll) {
-+        if (coll == null) {
-+            throw new NullPointerException("The collection must not be null");
-+        }
-+        if (coll instanceof BoundedCollection) {
-+            return ((BoundedCollection) coll).isFull();
-+        }
-+        try {
-+            BoundedCollection bcoll = UnmodifiableBoundedCollection.decorateUsing(coll);
-+            return bcoll.isFull();
-+
-+        } catch (IllegalArgumentException ex) {
-+            return false;
-+        }
-+    }
-+
-+    /**
-+     * Get the maximum number of elements that the Collection can contain.
-+     * <p/>
-+     * This method uses the {@link BoundedCollection} interface to determine the
-+     * maximum size. If the collection does not implement this interface then
-+     * -1 is returned.
-+     * <p/>
-+     * The collection does not have to implement this interface directly.
-+     * If the collection has been decorated using the decorators subpackage
-+     * then these will be removed to access the BoundedCollection.
-+     *
-+     * @param coll the collection to check
-+     * @return the maximum size of the BoundedCollection, -1 if no maximum size
-+     * @throws NullPointerException if the collection is null
-+     */
-+    public static int maxSize(Collection coll) {
-+        if (coll == null) {
-+            throw new NullPointerException("The collection must not be null");
-+        }
-+        if (coll instanceof BoundedCollection) {
-+            return ((BoundedCollection) coll).maxSize();
-+        }
-+        try {
-+            BoundedCollection bcoll = UnmodifiableBoundedCollection.decorateUsing(coll);
-+            return bcoll.maxSize();
-+
-+        } catch (IllegalArgumentException ex) {
-+            return -1;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized collection backed by the given collection.
-+     * <p/>
-+     * You must manually synchronize on the returned buffer's iterator to
-+     * avoid non-deterministic behavior:
-+     * <p/>
-+     * <pre>
-+     * Collection c = CollectionUtils.synchronizedCollection(myCollection);
-+     * synchronized (c) {
-+     *     Iterator i = c.iterator();
-+     *     while (i.hasNext()) {
-+     *         process (i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param collection the collection to synchronize, must not be null
-+     * @return a synchronized collection backed by the given collection
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public static <E> Collection<E> synchronizedCollection(Collection<E> collection) {
-+        return SynchronizedCollection.decorate(collection);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable collection backed by the given collection.
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param collection the collection to make unmodifiable, must not be null
-+     * @return an unmodifiable collection backed by the given collection
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public static <E> Collection<E> unmodifiableCollection(Collection<E> collection) {
-+        return UnmodifiableCollection.decorate(collection);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) collection backed by the given collection.
-+     * <p/>
-+     * Only objects that pass the test in the given predicate can be added to the collection.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * It is important not to use the original collection after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param collection the collection to predicate, must not be null
-+     * @param predicate  the predicate for the collection, must not be null
-+     * @return a predicated collection backed by the given collection
-+     * @throws IllegalArgumentException if the Collection is null
-+     */
-+    public static <E> Collection<E> predicatedCollection(Collection<E> collection, Predicate<? super E> predicate) {
-+        return PredicatedCollection.decorate(collection, predicate);
-+    }
-+
-+    /**
-+     * Returns a typed collection backed by the given collection.
-+     * <p/>
-+     * Only objects of the specified type can be added to the collection.
-+     *
-+     * @param collection the collection to limit to a specific type, must not be null
-+     * @param type       the type of objects which may be added to the collection
-+     * @return a typed collection backed by the specified collection
-+     * @deprecated Obsoleted by Java 1.5 Generics.
-+     */
-+    public static <E> Collection<E> typedCollection(Collection<E> collection, Class<E> type) {
-+        return TypedCollection.decorate(collection, type);
-+    }
-+
-+    /**
-+     * Returns a transformed bag backed by the given collection.
-+     * <p/>
-+     * Each object is passed through the transformer as it is added to the
-+     * Collection. It is important not to use the original collection after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param collection  the collection to predicate, must not be null
-+     * @param transformer the transformer for the collection, must not be null
-+     * @return a transformed collection backed by the given collection
-+     * @throws IllegalArgumentException if the Collection or Transformer is null
-+     */
-+    public static <I,O> Collection<O> transformedCollection(Collection<I> collection, Transformer<? super I, ? extends O> transformer) {
-+        return TransformedCollection.decorate(collection, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/ComparatorUtils.java
-@@ -0,0 +1,233 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.comparators.*;
-+
-+import java.util.Collection;
-+import java.util.Comparator;
-+
-+/**
-+ * Provides convenient static utility methods for <Code>Comparator</Code>
-+ * objects.
-+ * <p/>
-+ * Most of the functionality in this class can also be found in the
-+ * <code>comparators</code> package. This class merely provides a
-+ * convenient central place if you have use for more than one class
-+ * in the <code>comparators</code> subpackage.
-+ *
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public class ComparatorUtils {
-+
-+    /**
-+     * ComparatorUtils should not normally be instantiated.
-+     */
-+    public ComparatorUtils() {
-+    }
-+
-+    /**
-+     * Comparator for natural sort order.
-+     *
-+     * @see ComparableComparator#getInstance
-+     */
-+    public static final Comparator NATURAL_COMPARATOR = ComparableComparator.getInstance();
-+
-+    /**
-+     * Gets a comparator that uses the natural order of the objects.
-+     *
-+     * @return a comparator which uses natural order
-+     */
-+    public static Comparator naturalComparator() {
-+        return NATURAL_COMPARATOR;
-+    }
-+
-+    /**
-+     * Gets a comparator that compares using two {@link Comparator}s.
-+     * <p/>
-+     * The second comparator is used if the first comparator returns equal.
-+     *
-+     * @param comparator1 the first comparator to use, not null
-+     * @param comparator2 the first comparator to use, not null
-+     * @return a {@link ComparatorChain} formed from the two comparators
-+     * @throws NullPointerException if either comparator is null
-+     * @see ComparatorChain
-+     */
-+    public static <T> Comparator<T> chainedComparator(Comparator<T> comparator1, Comparator<T> comparator2) {
-+        return chainedComparator(new Comparator[]{comparator1, comparator2});
-+    }
-+
-+    /**
-+     * Gets a comparator that compares using an array of {@link Comparator}s, applied
-+     * in sequence until one returns not equal or the array is exhausted.
-+     *
-+     * @param comparators the comparators to use, not null or empty or containing nulls
-+     * @return a {@link ComparatorChain} formed from the input comparators
-+     * @throws NullPointerException if comparators array is null or contains a null
-+     * @see ComparatorChain
-+     */
-+    public static <T> Comparator<T> chainedComparator(Comparator<T>[] comparators) {
-+        ComparatorChain chain = new ComparatorChain();
-+        for (int i = 0; i < comparators.length; i++) {
-+            if (comparators[i] == null) {
-+                throw new NullPointerException("Comparator cannot be null");
-+            }
-+            chain.addComparator(comparators[i]);
-+        }
-+        return chain;
-+    }
-+
-+    /**
-+     * Gets a comparator that compares using a collection of {@link Comparator}s,
-+     * applied in (default iterator) sequence until one returns not equal or the
-+     * collection is exhausted.
-+     *
-+     * @param comparators the comparators to use, not null or empty or containing nulls
-+     * @return a {@link ComparatorChain} formed from the input comparators
-+     * @throws NullPointerException if comparators collection is null or contains a null
-+     * @throws ClassCastException   if the comparators collection contains the wrong object type
-+     * @see ComparatorChain
-+     */
-+    public static <T> Comparator<T> chainedComparator(Collection<T> comparators) {
-+        return chainedComparator((Comparator[]) comparators.toArray(new Comparator[comparators.size()]));
-+    }
-+
-+    /**
-+     * Gets a comparator that reverses the order of the given comparator.
-+     *
-+     * @param comparator the comparator to reverse
-+     * @return a comparator that reverses the order of the input comparator
-+     * @see ReverseComparator
-+     */
-+    public static <T> Comparator<T> reversedComparator(Comparator<T> comparator) {
-+        if (comparator == null) {
-+            comparator = NATURAL_COMPARATOR;
-+        }
-+        return new ReverseComparator(comparator);
-+    }
-+
-+    /**
-+     * Gets a Comparator that can sort Boolean objects.
-+     * <p/>
-+     * The parameter specifies whether true or false is sorted first.
-+     * <p/>
-+     * The comparator throws NullPointerException if a null value is compared.
-+     *
-+     * @param trueFirst when <code>true</code>, sort
-+     *                  <code>true</code> {@link Boolean}s before
-+     *                  <code>false</code> {@link Boolean}s.
-+     * @return a comparator that sorts booleans
-+     */
-+    public static Comparator<Boolean> booleanComparator(boolean trueFirst) {
-+        return BooleanComparator.getBooleanComparator(trueFirst);
-+    }
-+
-+    /**
-+     * Gets a Comparator that controls the comparison of <code>null</code> values.
-+     * <p/>
-+     * The returned comparator will consider a null value to be less than
-+     * any nonnull value, and equal to any other null value.  Two nonnull
-+     * values will be evaluated with the given comparator.
-+     *
-+     * @param comparator the comparator that wants to allow nulls
-+     * @return a version of that comparator that allows nulls
-+     * @see NullComparator
-+     */
-+    public static <T> Comparator<T> nullLowComparator(Comparator<T> comparator) {
-+        if (comparator == null) {
-+            comparator = NATURAL_COMPARATOR;
-+        }
-+        return new NullComparator(comparator, false);
-+    }
-+
-+    /**
-+     * Gets a Comparator that controls the comparison of <code>null</code> values.
-+     * <p/>
-+     * The returned comparator will consider a null value to be greater than
-+     * any nonnull value, and equal to any other null value.  Two nonnull
-+     * values will be evaluated with the given comparator.
-+     *
-+     * @param comparator the comparator that wants to allow nulls
-+     * @return a version of that comparator that allows nulls
-+     * @see NullComparator
-+     */
-+    public static <T> Comparator<T> nullHighComparator(Comparator<T> comparator) {
-+        if (comparator == null) {
-+            comparator = NATURAL_COMPARATOR;
-+        }
-+        return new NullComparator(comparator, true);
-+    }
-+
-+    /**
-+     * Gets a Comparator that passes transformed objects to the given comparator.
-+     * <p/>
-+     * Objects passed to the returned comparator will first be transformed
-+     * by the given transformer before they are compared by the given
-+     * comparator.
-+     *
-+     * @param comparator  the sort order to use
-+     * @param transformer the transformer to use
-+     * @return a comparator that transforms its input objects before comparing them
-+     * @see TransformingComparator
-+     */
-+    public static <I,O> Comparator<O> transformedComparator(Comparator<I> comparator, Transformer<I, O> transformer) {
-+        if (comparator == null) {
-+            comparator = NATURAL_COMPARATOR;
-+        }
-+        return new TransformingComparator(transformer, comparator);
-+    }
-+
-+    /**
-+     * Returns the smaller of the given objects according to the given
-+     * comparator, returning the second object if the comparator
-+     * returns equal.
-+     *
-+     * @param o1         the first object to compare
-+     * @param o2         the second object to compare
-+     * @param comparator the sort order to use
-+     * @return the smaller of the two objects
-+     */
-+    public static <T> T min(T o1, T o2, Comparator<T> comparator) {
-+        if (comparator == null) {
-+            comparator = NATURAL_COMPARATOR;
-+        }
-+        int c = comparator.compare(o1, o2);
-+        return (c < 0) ? o1 : o2;
-+    }
-+
-+    /**
-+     * Returns the larger of the given objects according to the given
-+     * comparator, returning the second object if the comparator
-+     * returns equal.
-+     *
-+     * @param o1         the first object to compare
-+     * @param o2         the second object to compare
-+     * @param comparator the sort order to use
-+     * @return the larger of the two objects
-+     */
-+    public static <T> T max(T o1, T o2, Comparator<T> comparator) {
-+        if (comparator == null) {
-+            comparator = NATURAL_COMPARATOR;
-+        }
-+        int c = comparator.compare(o1, o2);
-+        return (c > 0) ? o1 : o2;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/EnumerationUtils.java
-@@ -0,0 +1,53 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.iterators.EnumerationIterator;
-+
-+import java.util.Enumeration;
-+import java.util.List;
-+
-+/**
-+ * Provides utility methods for {@link Enumeration} instances.
-+ *
-+ * @author Matt Hall, John Watkinson, <a href="mailto:ggregory at seagullsw.com">Gary Gregory</a>
-+ * @version $Id: EnumerationUtils.java,v 1.1 2005/10/11 17:05:19 pents90 Exp $
-+ * @since Commons Collections 3.0
-+ */
-+public class EnumerationUtils {
-+
-+    /**
-+     * EnumerationUtils is not normally instantiated.
-+     */
-+    public EnumerationUtils() {
-+        // no init.
-+    }
-+
-+    /**
-+     * Creates a list based on an enumeration.
-+     * <p/>
-+     * <p>As the enumeration is traversed, an ArrayList of its values is
-+     * created. The new list is returned.</p>
-+     *
-+     * @param enumeration the enumeration to traverse, which should not be <code>null</code>.
-+     * @throws NullPointerException if the enumeration parameter is <code>null</code>.
-+     */
-+    public static <E> List<E> toList(Enumeration<E> enumeration) {
-+        return IteratorUtils.toList(new EnumerationIterator(enumeration));
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/ExtendedProperties.java
-@@ -0,0 +1,1613 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.io.*;
-+import java.util.*;
-+
-+/**
-+ * This class extends normal Java properties by adding the possibility
-+ * to use the same key many times concatenating the value strings
-+ * instead of overwriting them.
-+ * <p/>
-+ * <b>Please consider using the <code>PropertiesConfiguration</code> class in
-+ * Commons-Configuration as soon as it is released.</b>
-+ * <p/>
-+ * The Extended Properties syntax is explained here:
-+ * <p/>
-+ * <ul>
-+ * <li>
-+ * Each property has the syntax <code>key = value</code>
-+ * </li>
-+ * <li>
-+ * The <i>key</i> may use any character but the equal sign '='.
-+ * </li>
-+ * <li>
-+ * <i>value</i> may be separated on different lines if a backslash
-+ * is placed at the end of the line that continues below.
-+ * </li>
-+ * <li>
-+ * If <i>value</i> is a list of strings, each token is separated
-+ * by a comma ','.
-+ * </li>
-+ * <li>
-+ * Commas in each token are escaped placing a backslash right before
-+ * the comma.
-+ * </li>
-+ * <li>
-+ * Backslashes are escaped by using two consecutive backslashes i.e. \\
-+ * </li>
-+ * <li>
-+ * If a <i>key</i> is used more than once, the values are appended
-+ * like if they were on the same line separated with commas.
-+ * </li>
-+ * <li>
-+ * Blank lines and lines starting with character '#' are skipped.
-+ * </li>
-+ * <li>
-+ * If a property is named "include" (or whatever is defined by
-+ * setInclude() and getInclude() and the value of that property is
-+ * the full path to a file on disk, that file will be included into
-+ * the ConfigurationsRepository. You can also pull in files relative
-+ * to the parent configuration file. So if you have something
-+ * like the following:
-+ * <p/>
-+ * include = additional.properties
-+ * <p/>
-+ * Then "additional.properties" is expected to be in the same
-+ * directory as the parent configuration file.
-+ * <p/>
-+ * Duplicate name values will be replaced, so be careful.
-+ * <p/>
-+ * </li>
-+ * </ul>
-+ * <p/>
-+ * <p>Here is an example of a valid extended properties file:
-+ * <p/>
-+ * <p><pre>
-+ *      # lines starting with # are comments
-+ * <p/>
-+ *      # This is the simplest property
-+ *      key = value
-+ * <p/>
-+ *      # A long property may be separated on multiple lines
-+ *      longvalue = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
-+ *                  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-+ * <p/>
-+ *      # This is a property with many tokens
-+ *      tokens_on_a_line = first token, second token
-+ * <p/>
-+ *      # This sequence generates exactly the same result
-+ *      tokens_on_multiple_lines = first token
-+ *      tokens_on_multiple_lines = second token
-+ * <p/>
-+ *      # commas may be escaped in tokens
-+ *      commas.escaped = Hi\, what'up?
-+ * </pre>
-+ * <p/>
-+ * <p><b>NOTE</b>: this class has <b>not</b> been written for
-+ * performance nor low memory usage.  In fact, it's way slower than it
-+ * could be and generates too much memory garbage.  But since
-+ * performance is not an issue during intialization (and there is not
-+ * much time to improve it), I wrote it this way.  If you don't like
-+ * it, go ahead and tune it up!
-+ *
-+ * @author <a href="mailto:stefano at apache.org">Stefano Mazzocchi</a>
-+ * @author <a href="mailto:jon at latchkey.com">Jon S. Stevens</a>
-+ * @author <a href="mailto:daveb at miceda-data">Dave Bryson</a>
-+ * @author <a href="mailto:jvanzyl at periapt.com">Jason van Zyl</a>
-+ * @author <a href="mailto:geirm at optonline.net">Geir Magnusson Jr.</a>
-+ * @author <a href="mailto:leon at opticode.co.za">Leon Messerschmidt</a>
-+ * @author <a href="mailto:kjohnson at transparent.com">Kent Johnson</a>
-+ * @author <a href="mailto:dlr at finemaltcoding.com">Daniel Rall</a>
-+ * @author <a href="mailto:ipriha at surfeu.fi">Ilkka Priha</a>
-+ * @author Janek Bogucki
-+ * @author Mohan Kishore
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public class ExtendedProperties extends Hashtable {
-+
-+    /**
-+     * Default configurations repository.
-+     */
-+    private ExtendedProperties defaults;
-+
-+    /**
-+     * The file connected to this repository (holding comments and
-+     * such).
-+     *
-+     * @serial
-+     */
-+    protected String file;
-+
-+    /**
-+     * Base path of the configuration file used to create
-+     * this ExtendedProperties object.
-+     */
-+    protected String basePath;
-+
-+    /**
-+     * File separator.
-+     */
-+    protected String fileSeparator = System.getProperty("file.separator");
-+
-+    /**
-+     * Has this configuration been intialized.
-+     */
-+    protected boolean isInitialized = false;
-+
-+    /**
-+     * This is the name of the property that can point to other
-+     * properties file for including other properties files.
-+     */
-+    protected static String include = "include";
-+
-+    /**
-+     * These are the keys in the order they listed
-+     * in the configuration file. This is useful when
-+     * you wish to perform operations with configuration
-+     * information in a particular order.
-+     */
-+    protected ArrayList<String> keysAsListed = new ArrayList<String>();
-+
-+    protected final static String START_TOKEN = "${";
-+    protected final static String END_TOKEN = "}";
-+
-+
-+    /**
-+     * Interpolate key names to handle ${key} stuff
-+     *
-+     * @param base string to interpolate
-+     * @return returns the key name with the ${key} substituted
-+     */
-+    protected String interpolate(String base) {
-+        // COPIED from [configuration] 2003-12-29
-+        return (interpolateHelper(base, null));
-+    }
-+
-+    /**
-+     * Recursive handler for multiple levels of interpolation.
-+     * <p/>
-+     * When called the first time, priorVariables should be null.
-+     *
-+     * @param base           string with the ${key} variables
-+     * @param priorVariables serves two purposes: to allow checking for
-+     *                       loops, and creating a meaningful exception message should a loop
-+     *                       occur.  It's 0'th element will be set to the value of base from
-+     *                       the first call.  All subsequent interpolated variables are added
-+     *                       afterward.
-+     * @return the string with the interpolation taken care of
-+     */
-+    protected String interpolateHelper(String base, List priorVariables) {
-+        // COPIED from [configuration] 2003-12-29
-+        if (base == null) {
-+            return null;
-+        }
-+
-+        // on the first call initialize priorVariables
-+        // and add base as the first element
-+        if (priorVariables == null) {
-+            priorVariables = new ArrayList();
-+            priorVariables.add(base);
-+        }
-+
-+        int begin = -1;
-+        int end = -1;
-+        int prec = 0 - END_TOKEN.length();
-+        String variable = null;
-+        StringBuffer result = new StringBuffer();
-+
-+        // FIXME: we should probably allow the escaping of the start token
-+        while (((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) > -1) && ((end = base.indexOf(END_TOKEN, begin)) > -1)) {
-+            result.append(base.substring(prec + END_TOKEN.length(), begin));
-+            variable = base.substring(begin + START_TOKEN.length(), end);
-+
-+            // if we've got a loop, create a useful exception message and throw
-+            if (priorVariables.contains(variable)) {
-+                String initialBase = priorVariables.remove(0).toString();
-+                priorVariables.add(variable);
-+                StringBuffer priorVariableSb = new StringBuffer();
-+
-+                // create a nice trace of interpolated variables like so:
-+                // var1->var2->var3
-+                for (Iterator it = priorVariables.iterator(); it.hasNext();) {
-+                    priorVariableSb.append(it.next());
-+                    if (it.hasNext()) {
-+                        priorVariableSb.append("->");
-+                    }
-+                }
-+
-+                throw new IllegalStateException("infinite loop in property interpolation of " + initialBase + ": " + priorVariableSb.toString());
-+            }
-+            // otherwise, add this variable to the interpolation list.
-+            else {
-+                priorVariables.add(variable);
-+            }
-+
-+            //QUESTION: getProperty or getPropertyDirect
-+            Object value = getProperty(variable);
-+            if (value != null) {
-+                result.append(interpolateHelper(value.toString(), priorVariables));
-+
-+                // pop the interpolated variable off the stack
-+                // this maintains priorVariables correctness for
-+                // properties with multiple interpolations, e.g.
-+                // prop.name=${some.other.prop1}/blahblah/${some.other.prop2}
-+                priorVariables.remove(priorVariables.size() - 1);
-+            } else if (defaults != null && defaults.getString(variable, null) != null) {
-+                result.append(defaults.getString(variable));
-+            } else {
-+                //variable not defined - so put it back in the value
-+                result.append(START_TOKEN).append(variable).append(END_TOKEN);
-+            }
-+            prec = end;
-+        }
-+        result.append(base.substring(prec + END_TOKEN.length(), base.length()));
-+
-+        return result.toString();
-+    }
-+
-+    /**
-+     * Inserts a backslash before every comma and backslash.
-+     */
-+    private static String escape(String s) {
-+        StringBuffer buf = new StringBuffer(s);
-+        for (int i = 0; i < buf.length(); i++) {
-+            char c = buf.charAt(i);
-+            if (c == ',' || c == '\\') {
-+                buf.insert(i, '\\');
-+                i++;
-+            }
-+        }
-+        return buf.toString();
-+    }
-+
-+    /**
-+     * Removes a backslash from every pair of backslashes.
-+     */
-+    private static String unescape(String s) {
-+        StringBuffer buf = new StringBuffer(s);
-+        for (int i = 0; i < buf.length() - 1; i++) {
-+            char c1 = buf.charAt(i);
-+            char c2 = buf.charAt(i + 1);
-+            if (c1 == '\\' && c2 == '\\') {
-+                buf.deleteCharAt(i);
-+            }
-+        }
-+        return buf.toString();
-+    }
-+
-+    /**
-+     * Counts the number of successive times 'ch' appears in the
-+     * 'line' before the position indicated by the 'index'.
-+     */
-+    private static int countPreceding(String line, int index, char ch) {
-+        int i;
-+        for (i = index - 1; i >= 0; i--) {
-+            if (line.charAt(i) != ch) {
-+                break;
-+            }
-+        }
-+        return index - 1 - i;
-+    }
-+
-+    /**
-+     * Checks if the line ends with odd number of backslashes
-+     */
-+    private static boolean endsWithSlash(String line) {
-+        if (!line.endsWith("\\")) {
-+            return false;
-+        }
-+        return (countPreceding(line, line.length() - 1, '\\') % 2 == 0);
-+    }
-+
-+    /**
-+     * This class is used to read properties lines.  These lines do
-+     * not terminate with new-line chars but rather when there is no
-+     * backslash sign a the end of the line.  This is used to
-+     * concatenate multiple lines for readability.
-+     */
-+    static class PropertiesReader extends LineNumberReader {
-+        /**
-+         * Constructor.
-+         *
-+         * @param reader A Reader.
-+         */
-+        public PropertiesReader(Reader reader) {
-+            super(reader);
-+        }
-+
-+        /**
-+         * Read a property.
-+         *
-+         * @return a String property
-+         * @throws IOException if there is difficulty reading the source.
-+         */
-+        public String readProperty() throws IOException {
-+            StringBuffer buffer = new StringBuffer();
-+
-+            try {
-+                while (true) {
-+                    String line = readLine().trim();
-+                    if ((line.length() != 0) && (line.charAt(0) != '#')) {
-+                        if (endsWithSlash(line)) {
-+                            line = line.substring(0, line.length() - 1);
-+                            buffer.append(line);
-+                        } else {
-+                            buffer.append(line);
-+                            break;
-+                        }
-+                    }
-+                }
-+            } catch (NullPointerException ex) {
-+                return null;
-+            }
-+
-+            return buffer.toString();
-+        }
-+    }
-+
-+    /**
-+     * This class divides into tokens a property value.  Token
-+     * separator is "," but commas into the property value are escaped
-+     * using the backslash in front.
-+     */
-+    static class PropertiesTokenizer extends StringTokenizer {
-+        /**
-+         * The property delimiter used while parsing (a comma).
-+         */
-+        static final String DELIMITER = ",";
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param string A String.
-+         */
-+        public PropertiesTokenizer(String string) {
-+            super(string, DELIMITER);
-+        }
-+
-+        /**
-+         * Check whether the object has more tokens.
-+         *
-+         * @return True if the object has more tokens.
-+         */
-+        public boolean hasMoreTokens() {
-+            return super.hasMoreTokens();
-+        }
-+
-+        /**
-+         * Get next token.
-+         *
-+         * @return A String.
-+         */
-+        public String nextToken() {
-+            StringBuffer buffer = new StringBuffer();
-+
-+            while (hasMoreTokens()) {
-+                String token = super.nextToken();
-+                if (endsWithSlash(token)) {
-+                    buffer.append(token.substring(0, token.length() - 1));
-+                    buffer.append(DELIMITER);
-+                } else {
-+                    buffer.append(token);
-+                    break;
-+                }
-+            }
-+
-+            return buffer.toString().trim();
-+        }
-+    }
-+
-+    /**
-+     * Creates an empty extended properties object.
-+     */
-+    public ExtendedProperties() {
-+        super();
-+    }
-+
-+    /**
-+     * Creates and loads the extended properties from the specified file.
-+     *
-+     * @param file the filename to load
-+     * @throws IOException if a file error occurs
-+     */
-+    public ExtendedProperties(String file) throws IOException {
-+        this(file, null);
-+    }
-+
-+    /**
-+     * Creates and loads the extended properties from the specified file.
-+     *
-+     * @param file        the filename to load
-+     * @param defaultFile a second filename to load default values from
-+     * @throws IOException if a file error occurs
-+     */
-+    public ExtendedProperties(String file, String defaultFile) throws IOException {
-+        this.file = file;
-+
-+        basePath = new File(file).getAbsolutePath();
-+        basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1);
-+
-+        FileInputStream in = null;
-+        try {
-+            in = new FileInputStream(file);
-+            this.load(in);
-+        } finally {
-+            try {
-+                if (in != null) {
-+                    in.close();
-+                }
-+            } catch (IOException ex) {
-+            }
-+        }
-+
-+        if (defaultFile != null) {
-+            defaults = new ExtendedProperties(defaultFile);
-+        }
-+    }
-+
-+    /**
-+     * Indicate to client code whether property
-+     * resources have been initialized or not.
-+     */
-+    public boolean isInitialized() {
-+        return isInitialized;
-+    }
-+
-+    /**
-+     * Gets the property value for including other properties files.
-+     * By default it is "include".
-+     *
-+     * @return A String.
-+     */
-+    public String getInclude() {
-+        return include;
-+    }
-+
-+    /**
-+     * Sets the property value for including other properties files.
-+     * By default it is "include".
-+     *
-+     * @param inc A String.
-+     */
-+    public void setInclude(String inc) {
-+        include = inc;
-+    }
-+
-+    /**
-+     * Load the properties from the given input stream.
-+     *
-+     * @param input the InputStream to load from
-+     * @throws IOException if an IO error occurs
-+     */
-+    public void load(InputStream input) throws IOException {
-+        load(input, null);
-+    }
-+
-+    /**
-+     * Load the properties from the given input stream
-+     * and using the specified encoding.
-+     *
-+     * @param input the InputStream to load from
-+     * @param enc   the encoding to use
-+     * @throws IOException if an IO error occurs
-+     */
-+    public synchronized void load(InputStream input, String enc) throws IOException {
-+        PropertiesReader reader = null;
-+        if (enc != null) {
-+            try {
-+                reader = new PropertiesReader(new InputStreamReader(input, enc));
-+
-+            } catch (UnsupportedEncodingException ex) {
-+                // Another try coming up....
-+            }
-+        }
-+
-+        if (reader == null) {
-+            try {
-+                reader = new PropertiesReader(new InputStreamReader(input, "8859_1"));
-+
-+            } catch (UnsupportedEncodingException ex) {
-+                // ISO8859-1 support is required on java platforms but....
-+                // If it's not supported, use the system default encoding
-+                reader = new PropertiesReader(new InputStreamReader(input));
-+            }
-+        }
-+
-+        try {
-+            while (true) {
-+                String line = reader.readProperty();
-+                int equalSign = line.indexOf('=');
-+
-+                if (equalSign > 0) {
-+                    String key = line.substring(0, equalSign).trim();
-+                    String value = line.substring(equalSign + 1).trim();
-+
-+                    // Configure produces lines like this ... just ignore them
-+                    if ("".equals(value)) {
-+                        continue;
-+                    }
-+
-+                    if (getInclude() != null && key.equalsIgnoreCase(getInclude())) {
-+                        // Recursively load properties files.
-+                        File file = null;
-+
-+                        if (value.startsWith(fileSeparator)) {
-+                            // We have an absolute path so we'll use this
-+                            file = new File(value);
-+
-+                        } else {
-+                            // We have a relative path, and we have two 
-+                            // possible forms here. If we have the "./" form
-+                            // then just strip that off first before continuing.
-+                            if (value.startsWith("." + fileSeparator)) {
-+                                value = value.substring(2);
-+                            }
-+
-+                            file = new File(basePath + value);
-+                        }
-+
-+                        if (file != null && file.exists() && file.canRead()) {
-+                            load(new FileInputStream(file));
-+                        }
-+                    } else {
-+                        addProperty(key, value);
-+                    }
-+                }
-+            }
-+        } catch (NullPointerException ex) {
-+            // Should happen only when EOF is reached.
-+            return;
-+        } finally {
-+            // Loading is initializing
-+            isInitialized = true;
-+        }
-+    }
-+
-+    /**
-+     * Gets a property from the configuration.
-+     *
-+     * @param key property to retrieve
-+     * @return value as object. Will return user value if exists,
-+     *         if not then default value if exists, otherwise null
-+     */
-+    public Object getProperty(String key) {
-+        // first, try to get from the 'user value' store
-+        Object obj = this.get(key);
-+
-+        if (obj == null) {
-+            // if there isn't a value there, get it from the
-+            // defaults if we have them
-+            if (defaults != null) {
-+                obj = defaults.get(key);
-+            }
-+        }
-+
-+        return obj;
-+    }
-+
-+    /**
-+     * Add a property to the configuration. If it already
-+     * exists then the value stated here will be added
-+     * to the configuration entry. For example, if
-+     * <p/>
-+     * <code>resource.loader = file</code>
-+     * <p/>
-+     * is already present in the configuration and you
-+     * <p/>
-+     * <code>addProperty("resource.loader", "classpath")</code>
-+     * <p/>
-+     * Then you will end up with a Vector like the
-+     * following:
-+     * <p/>
-+     * <code>["file", "classpath"]</code>
-+     *
-+     * @param key   the key to add
-+     * @param value the value to add
-+     */
-+    public void addProperty(String key, Object value) {
-+        if (value instanceof String) {
-+            String str = (String) value;
-+            if (str.indexOf(PropertiesTokenizer.DELIMITER) > 0) {
-+                // token contains commas, so must be split apart then added
-+                PropertiesTokenizer tokenizer = new PropertiesTokenizer(str);
-+                while (tokenizer.hasMoreTokens()) {
-+                    String token = tokenizer.nextToken();
-+                    addPropertyInternal(key, unescape(token));
-+                }
-+            } else {
-+                // token contains no commas, so can be simply added
-+                addPropertyInternal(key, unescape(str));
-+            }
-+        } else {
-+            addPropertyInternal(key, value);
-+        }
-+
-+        // Adding a property connotes initialization
-+        isInitialized = true;
-+    }
-+
-+    /**
-+     * Adds a key/value pair to the map.  This routine does
-+     * no magic morphing.  It ensures the keylist is maintained
-+     *
-+     * @param key   the key to store at
-+     * @param value the decoded object to store
-+     */
-+    private void addPropertyDirect(String key, Object value) {
-+        // safety check
-+        if (!containsKey(key)) {
-+            keysAsListed.add(key);
-+        }
-+        put(key, value);
-+    }
-+
-+    /**
-+     * Adds a decoded property to the map w/o checking for commas - used
-+     * internally when a property has been broken up into
-+     * strings that could contain escaped commas to prevent
-+     * the inadvertent vectorization.
-+     * <p/>
-+     * Thanks to Leon Messerschmidt for this one.
-+     *
-+     * @param key   the key to store at
-+     * @param value the decoded object to store
-+     */
-+    private void addPropertyInternal(String key, Object value) {
-+        Object current = this.get(key);
-+
-+        if (current instanceof String) {
-+            // one object already in map - convert it to a vector
-+            Vector v = new Vector(2);
-+            v.addElement(current);
-+            v.addElement(value);
-+            put(key, v);
-+
-+        } else if (current instanceof Vector) {
-+            // already a vector - just add the new token
-+            ((Vector) current).addElement(value);
-+
-+        } else {
-+            // brand new key - store in keysAsListed to retain order
-+            if (!containsKey(key)) {
-+                keysAsListed.add(key);
-+            }
-+            put(key, value);
-+        }
-+    }
-+
-+    /**
-+     * Set a property, this will replace any previously
-+     * set values. Set values is implicitly a call
-+     * to clearProperty(key), addProperty(key,value).
-+     *
-+     * @param key   the key to set
-+     * @param value the value to set
-+     */
-+    public void setProperty(String key, Object value) {
-+        clearProperty(key);
-+        addProperty(key, value);
-+    }
-+
-+    /**
-+     * Save the properties to the given output stream.
-+     * <p/>
-+     * The stream is not closed, but it is flushed.
-+     *
-+     * @param output an OutputStream, may be null
-+     * @param header a textual comment to act as a file header
-+     * @throws IOException if an IO error occurs
-+     */
-+    public synchronized void save(OutputStream output, String header) throws IOException {
-+        if (output == null) {
-+            return;
-+        }
-+        PrintWriter theWrtr = new PrintWriter(output);
-+        if (header != null) {
-+            theWrtr.println(header);
-+        }
-+
-+        Enumeration theKeys = keys();
-+        while (theKeys.hasMoreElements()) {
-+            String key = (String) theKeys.nextElement();
-+            Object value = get(key);
-+            if (value != null) {
-+                if (value instanceof String) {
-+                    StringBuffer currentOutput = new StringBuffer();
-+                    currentOutput.append(key);
-+                    currentOutput.append("=");
-+                    currentOutput.append(escape((String) value));
-+                    theWrtr.println(currentOutput.toString());
-+
-+                } else if (value instanceof Vector) {
-+                    Vector values = (Vector) value;
-+                    Enumeration valuesEnum = values.elements();
-+                    while (valuesEnum.hasMoreElements()) {
-+                        String currentElement = (String) valuesEnum.nextElement();
-+                        StringBuffer currentOutput = new StringBuffer();
-+                        currentOutput.append(key);
-+                        currentOutput.append("=");
-+                        currentOutput.append(escape(currentElement));
-+                        theWrtr.println(currentOutput.toString());
-+                    }
-+                }
-+            }
-+            theWrtr.println();
-+            theWrtr.flush();
-+        }
-+    }
-+
-+    /**
-+     * Combines an existing Hashtable with this Hashtable.
-+     * <p/>
-+     * Warning: It will overwrite previous entries without warning.
-+     *
-+     * @param props the properties to combine
-+     */
-+    public void combine(ExtendedProperties props) {
-+        for (Iterator it = props.getKeys(); it.hasNext();) {
-+            String key = (String) it.next();
-+            setProperty(key, props.get(key));
-+        }
-+    }
-+
-+    /**
-+     * Clear a property in the configuration.
-+     *
-+     * @param key the property key to remove along with corresponding value
-+     */
-+    public void clearProperty(String key) {
-+        if (containsKey(key)) {
-+            // we also need to rebuild the keysAsListed or else
-+            // things get *very* confusing
-+            for (int i = 0; i < keysAsListed.size(); i++) {
-+                if ((keysAsListed.get(i)).equals(key)) {
-+                    keysAsListed.remove(i);
-+                    break;
-+                }
-+            }
-+            remove(key);
-+        }
-+    }
-+
-+    /**
-+     * Get the list of the keys contained in the configuration
-+     * repository.
-+     *
-+     * @return an Iterator over the keys
-+     */
-+    public Iterator getKeys() {
-+        return keysAsListed.iterator();
-+    }
-+
-+    /**
-+     * Get the list of the keys contained in the configuration
-+     * repository that match the specified prefix.
-+     *
-+     * @param prefix the prefix to match
-+     * @return an Iterator of keys that match the prefix
-+     */
-+    public Iterator getKeys(String prefix) {
-+        Iterator keys = getKeys();
-+        ArrayList matchingKeys = new ArrayList();
-+
-+        while (keys.hasNext()) {
-+            Object key = keys.next();
-+
-+            if (key instanceof String && ((String) key).startsWith(prefix)) {
-+                matchingKeys.add(key);
-+            }
-+        }
-+        return matchingKeys.iterator();
-+    }
-+
-+    /**
-+     * Create an ExtendedProperties object that is a subset
-+     * of this one. Take into account duplicate keys
-+     * by using the setProperty() in ExtendedProperties.
-+     *
-+     * @param prefix the prefix to get a subset for
-+     * @return a new independent ExtendedProperties
-+     */
-+    public ExtendedProperties subset(String prefix) {
-+        ExtendedProperties c = new ExtendedProperties();
-+        Iterator keys = getKeys();
-+        boolean validSubset = false;
-+
-+        while (keys.hasNext()) {
-+            Object key = keys.next();
-+
-+            if (key instanceof String && ((String) key).startsWith(prefix)) {
-+                if (!validSubset) {
-+                    validSubset = true;
-+                }
-+
-+                /*
-+                 * Check to make sure that c.subset(prefix) doesn't
-+                 * blow up when there is only a single property
-+                 * with the key prefix. This is not a useful
-+                 * subset but it is a valid subset.
-+                 */
-+                String newKey = null;
-+                if (((String) key).length() == prefix.length()) {
-+                    newKey = prefix;
-+                } else {
-+                    newKey = ((String) key).substring(prefix.length() + 1);
-+                }
-+
-+                /*
-+                 *  use addPropertyDirect() - this will plug the data as 
-+                 *  is into the Map, but will also do the right thing
-+                 *  re key accounting
-+                 */
-+                c.addPropertyDirect(newKey, get(key));
-+            }
-+        }
-+
-+        if (validSubset) {
-+            return c;
-+        } else {
-+            return null;
-+        }
-+    }
-+
-+    /**
-+     * Display the configuration for debugging purposes to System.out.
-+     */
-+    public void display() {
-+        Iterator i = getKeys();
-+
-+        while (i.hasNext()) {
-+            String key = (String) i.next();
-+            Object value = get(key);
-+            System.out.println(key + " => " + value);
-+        }
-+    }
-+
-+    /**
-+     * Get a string associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated string.
-+     * @throws ClassCastException is thrown if the key maps to an
-+     *                            object that is not a String.
-+     */
-+    public String getString(String key) {
-+        return getString(key, null);
-+    }
-+
-+    /**
-+     * Get a string associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated string if key is found,
-+     *         default value otherwise.
-+     * @throws ClassCastException is thrown if the key maps to an
-+     *                            object that is not a String.
-+     */
-+    public String getString(String key, String defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof String) {
-+            return interpolate((String) value);
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return interpolate(defaults.getString(key, defaultValue));
-+            } else {
-+                return interpolate(defaultValue);
-+            }
-+        } else if (value instanceof Vector) {
-+            return interpolate((String) ((Vector) value).get(0));
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a String object");
-+        }
-+    }
-+
-+    /**
-+     * Get a list of properties associated with the given
-+     * configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated properties if key is found.
-+     * @throws ClassCastException       is thrown if the key maps to an
-+     *                                  object that is not a String/Vector.
-+     * @throws IllegalArgumentException if one of the tokens is
-+     *                                  malformed (does not contain an equals sign).
-+     */
-+    public Properties getProperties(String key) {
-+        return getProperties(key, new Properties());
-+    }
-+
-+    /**
-+     * Get a list of properties associated with the given
-+     * configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated properties if key is found.
-+     * @throws ClassCastException       is thrown if the key maps to an
-+     *                                  object that is not a String/Vector.
-+     * @throws IllegalArgumentException if one of the tokens is
-+     *                                  malformed (does not contain an equals sign).
-+     */
-+    public Properties getProperties(String key, Properties defaults) {
-+        /*
-+         * Grab an array of the tokens for this key.
-+         */
-+        String[] tokens = getStringArray(key);
-+
-+        // Each token is of the form 'key=value'.
-+        Properties props = new Properties(defaults);
-+        for (int i = 0; i < tokens.length; i++) {
-+            String token = tokens[i];
-+            int equalSign = token.indexOf('=');
-+            if (equalSign > 0) {
-+                String pkey = token.substring(0, equalSign).trim();
-+                String pvalue = token.substring(equalSign + 1).trim();
-+                props.put(pkey, pvalue);
-+            } else {
-+                throw new IllegalArgumentException('\'' + token + "' does not contain " + "an equals sign");
-+            }
-+        }
-+        return props;
-+    }
-+
-+    /**
-+     * Get an array of strings associated with the given configuration
-+     * key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated string array if key is found.
-+     * @throws ClassCastException is thrown if the key maps to an
-+     *                            object that is not a String/Vector.
-+     */
-+    public String[] getStringArray(String key) {
-+        Object value = get(key);
-+
-+        // What's your vector, Victor?
-+        Vector vector;
-+        if (value instanceof String) {
-+            vector = new Vector(1);
-+            vector.addElement(value);
-+
-+        } else if (value instanceof Vector) {
-+            vector = (Vector) value;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getStringArray(key);
-+            } else {
-+                return new String[0];
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a String/Vector object");
-+        }
-+
-+        String[] tokens = new String[vector.size()];
-+        for (int i = 0; i < tokens.length; i++) {
-+            tokens[i] = (String) vector.elementAt(i);
-+        }
-+
-+        return tokens;
-+    }
-+
-+    /**
-+     * Get a Vector of strings associated with the given configuration
-+     * key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated Vector.
-+     * @throws ClassCastException is thrown if the key maps to an
-+     *                            object that is not a Vector.
-+     */
-+    public Vector getVector(String key) {
-+        return getVector(key, null);
-+    }
-+
-+    /**
-+     * Get a Vector of strings associated with the given configuration
-+     * key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated Vector.
-+     * @throws ClassCastException is thrown if the key maps to an
-+     *                            object that is not a Vector.
-+     */
-+    public Vector getVector(String key, Vector defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof Vector) {
-+            return (Vector) value;
-+
-+        } else if (value instanceof String) {
-+            Vector v = new Vector(1);
-+            v.addElement(value);
-+            put(key, v);
-+            return v;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getVector(key, defaultValue);
-+            } else {
-+                return ((defaultValue == null) ? new Vector() : defaultValue);
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Vector object");
-+        }
-+    }
-+
-+    /**
-+     * Get a boolean associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated boolean.
-+     * @throws NoSuchElementException is thrown if the key doesn't
-+     *                                map to an existing object.
-+     * @throws ClassCastException     is thrown if the key maps to an
-+     *                                object that is not a Boolean.
-+     */
-+    public boolean getBoolean(String key) {
-+        Boolean b = getBoolean(key, null);
-+        if (b != null) {
-+            return b.booleanValue();
-+        } else {
-+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
-+        }
-+    }
-+
-+    /**
-+     * Get a boolean associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated boolean.
-+     * @throws ClassCastException is thrown if the key maps to an
-+     *                            object that is not a Boolean.
-+     */
-+    public boolean getBoolean(String key, boolean defaultValue) {
-+        return getBoolean(key, new Boolean(defaultValue)).booleanValue();
-+    }
-+
-+    /**
-+     * Get a boolean associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated boolean if key is found and has valid
-+     *         format, default value otherwise.
-+     * @throws ClassCastException is thrown if the key maps to an
-+     *                            object that is not a Boolean.
-+     */
-+    public Boolean getBoolean(String key, Boolean defaultValue) {
-+
-+        Object value = get(key);
-+
-+        if (value instanceof Boolean) {
-+            return (Boolean) value;
-+
-+        } else if (value instanceof String) {
-+            String s = testBoolean((String) value);
-+            Boolean b = new Boolean(s);
-+            put(key, b);
-+            return b;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getBoolean(key, defaultValue);
-+            } else {
-+                return defaultValue;
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Boolean object");
-+        }
-+    }
-+
-+    /**
-+     * Test whether the string represent by value maps to a boolean
-+     * value or not. We will allow <code>true</code>, <code>on</code>,
-+     * and <code>yes</code> for a <code>true</code> boolean value, and
-+     * <code>false</code>, <code>off</code>, and <code>no</code> for
-+     * <code>false</code> boolean values.  Case of value to test for
-+     * boolean status is ignored.
-+     *
-+     * @param value the value to test for boolean state
-+     * @return <code>true</code> or <code>false</code> if the supplied
-+     *         text maps to a boolean value, or <code>null</code> otherwise.
-+     */
-+    public String testBoolean(String value) {
-+        String s = value.toLowerCase();
-+
-+        if (s.equals("true") || s.equals("on") || s.equals("yes")) {
-+            return "true";
-+        } else if (s.equals("false") || s.equals("off") || s.equals("no")) {
-+            return "false";
-+        } else {
-+            return null;
-+        }
-+    }
-+
-+    /**
-+     * Get a byte associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated byte.
-+     * @throws NoSuchElementException is thrown if the key doesn't
-+     *                                map to an existing object.
-+     * @throws ClassCastException     is thrown if the key maps to an
-+     *                                object that is not a Byte.
-+     * @throws NumberFormatException  is thrown if the value mapped
-+     *                                by the key has not a valid number format.
-+     */
-+    public byte getByte(String key) {
-+        Byte b = getByte(key, null);
-+        if (b != null) {
-+            return b.byteValue();
-+        } else {
-+            throw new NoSuchElementException('\'' + key + " doesn't map to an existing object");
-+        }
-+    }
-+
-+    /**
-+     * Get a byte associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated byte.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Byte.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public byte getByte(String key, byte defaultValue) {
-+        return getByte(key, new Byte(defaultValue)).byteValue();
-+    }
-+
-+    /**
-+     * Get a byte associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated byte if key is found and has valid
-+     *         format, default value otherwise.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Byte.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public Byte getByte(String key, Byte defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof Byte) {
-+            return (Byte) value;
-+
-+        } else if (value instanceof String) {
-+            Byte b = new Byte((String) value);
-+            put(key, b);
-+            return b;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getByte(key, defaultValue);
-+            } else {
-+                return defaultValue;
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Byte object");
-+        }
-+    }
-+
-+    /**
-+     * Get a short associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated short.
-+     * @throws NoSuchElementException is thrown if the key doesn't
-+     *                                map to an existing object.
-+     * @throws ClassCastException     is thrown if the key maps to an
-+     *                                object that is not a Short.
-+     * @throws NumberFormatException  is thrown if the value mapped
-+     *                                by the key has not a valid number format.
-+     */
-+    public short getShort(String key) {
-+        Short s = getShort(key, null);
-+        if (s != null) {
-+            return s.shortValue();
-+        } else {
-+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
-+        }
-+    }
-+
-+    /**
-+     * Get a short associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated short.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Short.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public short getShort(String key, short defaultValue) {
-+        return getShort(key, new Short(defaultValue)).shortValue();
-+    }
-+
-+    /**
-+     * Get a short associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated short if key is found and has valid
-+     *         format, default value otherwise.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Short.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public Short getShort(String key, Short defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof Short) {
-+            return (Short) value;
-+
-+        } else if (value instanceof String) {
-+            Short s = new Short((String) value);
-+            put(key, s);
-+            return s;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getShort(key, defaultValue);
-+            } else {
-+                return defaultValue;
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Short object");
-+        }
-+    }
-+
-+    /**
-+     * The purpose of this method is to get the configuration resource
-+     * with the given name as an integer.
-+     *
-+     * @param name The resource name.
-+     * @return The value of the resource as an integer.
-+     */
-+    public int getInt(String name) {
-+        return getInteger(name);
-+    }
-+
-+    /**
-+     * The purpose of this method is to get the configuration resource
-+     * with the given name as an integer, or a default value.
-+     *
-+     * @param name The resource name
-+     * @param def  The default value of the resource.
-+     * @return The value of the resource as an integer.
-+     */
-+    public int getInt(String name, int def) {
-+        return getInteger(name, def);
-+    }
-+
-+    /**
-+     * Get a int associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated int.
-+     * @throws NoSuchElementException is thrown if the key doesn't
-+     *                                map to an existing object.
-+     * @throws ClassCastException     is thrown if the key maps to an
-+     *                                object that is not a Integer.
-+     * @throws NumberFormatException  is thrown if the value mapped
-+     *                                by the key has not a valid number format.
-+     */
-+    public int getInteger(String key) {
-+        Integer i = getInteger(key, null);
-+        if (i != null) {
-+            return i.intValue();
-+        } else {
-+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
-+        }
-+    }
-+
-+    /**
-+     * Get a int associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated int.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Integer.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public int getInteger(String key, int defaultValue) {
-+        Integer i = getInteger(key, null);
-+
-+        if (i == null) {
-+            return defaultValue;
-+        }
-+        return i.intValue();
-+    }
-+
-+    /**
-+     * Get a int associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated int if key is found and has valid
-+     *         format, default value otherwise.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Integer.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public Integer getInteger(String key, Integer defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof Integer) {
-+            return (Integer) value;
-+
-+        } else if (value instanceof String) {
-+            Integer i = new Integer((String) value);
-+            put(key, i);
-+            return i;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getInteger(key, defaultValue);
-+            } else {
-+                return defaultValue;
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Integer object");
-+        }
-+    }
-+
-+    /**
-+     * Get a long associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated long.
-+     * @throws NoSuchElementException is thrown if the key doesn't
-+     *                                map to an existing object.
-+     * @throws ClassCastException     is thrown if the key maps to an
-+     *                                object that is not a Long.
-+     * @throws NumberFormatException  is thrown if the value mapped
-+     *                                by the key has not a valid number format.
-+     */
-+    public long getLong(String key) {
-+        Long l = getLong(key, null);
-+        if (l != null) {
-+            return l.longValue();
-+        } else {
-+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
-+        }
-+    }
-+
-+    /**
-+     * Get a long associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated long.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Long.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public long getLong(String key, long defaultValue) {
-+        return getLong(key, new Long(defaultValue)).longValue();
-+    }
-+
-+    /**
-+     * Get a long associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated long if key is found and has valid
-+     *         format, default value otherwise.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Long.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public Long getLong(String key, Long defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof Long) {
-+            return (Long) value;
-+
-+        } else if (value instanceof String) {
-+            Long l = new Long((String) value);
-+            put(key, l);
-+            return l;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getLong(key, defaultValue);
-+            } else {
-+                return defaultValue;
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Long object");
-+        }
-+    }
-+
-+    /**
-+     * Get a float associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated float.
-+     * @throws NoSuchElementException is thrown if the key doesn't
-+     *                                map to an existing object.
-+     * @throws ClassCastException     is thrown if the key maps to an
-+     *                                object that is not a Float.
-+     * @throws NumberFormatException  is thrown if the value mapped
-+     *                                by the key has not a valid number format.
-+     */
-+    public float getFloat(String key) {
-+        Float f = getFloat(key, null);
-+        if (f != null) {
-+            return f.floatValue();
-+        } else {
-+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
-+        }
-+    }
-+
-+    /**
-+     * Get a float associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated float.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Float.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public float getFloat(String key, float defaultValue) {
-+        return getFloat(key, new Float(defaultValue)).floatValue();
-+    }
-+
-+    /**
-+     * Get a float associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated float if key is found and has valid
-+     *         format, default value otherwise.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Float.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public Float getFloat(String key, Float defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof Float) {
-+            return (Float) value;
-+
-+        } else if (value instanceof String) {
-+            Float f = new Float((String) value);
-+            put(key, f);
-+            return f;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getFloat(key, defaultValue);
-+            } else {
-+                return defaultValue;
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Float object");
-+        }
-+    }
-+
-+    /**
-+     * Get a double associated with the given configuration key.
-+     *
-+     * @param key The configuration key.
-+     * @return The associated double.
-+     * @throws NoSuchElementException is thrown if the key doesn't
-+     *                                map to an existing object.
-+     * @throws ClassCastException     is thrown if the key maps to an
-+     *                                object that is not a Double.
-+     * @throws NumberFormatException  is thrown if the value mapped
-+     *                                by the key has not a valid number format.
-+     */
-+    public double getDouble(String key) {
-+        Double d = getDouble(key, null);
-+        if (d != null) {
-+            return d.doubleValue();
-+        } else {
-+            throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
-+        }
-+    }
-+
-+    /**
-+     * Get a double associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated double.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Double.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public double getDouble(String key, double defaultValue) {
-+        return getDouble(key, new Double(defaultValue)).doubleValue();
-+    }
-+
-+    /**
-+     * Get a double associated with the given configuration key.
-+     *
-+     * @param key          The configuration key.
-+     * @param defaultValue The default value.
-+     * @return The associated double if key is found and has valid
-+     *         format, default value otherwise.
-+     * @throws ClassCastException    is thrown if the key maps to an
-+     *                               object that is not a Double.
-+     * @throws NumberFormatException is thrown if the value mapped
-+     *                               by the key has not a valid number format.
-+     */
-+    public Double getDouble(String key, Double defaultValue) {
-+        Object value = get(key);
-+
-+        if (value instanceof Double) {
-+            return (Double) value;
-+
-+        } else if (value instanceof String) {
-+            Double d = new Double((String) value);
-+            put(key, d);
-+            return d;
-+
-+        } else if (value == null) {
-+            if (defaults != null) {
-+                return defaults.getDouble(key, defaultValue);
-+            } else {
-+                return defaultValue;
-+            }
-+        } else {
-+            throw new ClassCastException('\'' + key + "' doesn't map to a Double object");
-+        }
-+    }
-+
-+    /**
-+     * Convert a standard properties class into a configuration class.
-+     *
-+     * @param props the properties object to convert
-+     * @return new ExtendedProperties created from props
-+     */
-+    public static ExtendedProperties convertProperties(Properties props) {
-+        ExtendedProperties c = new ExtendedProperties();
-+
-+        for (Enumeration e = props.keys(); e.hasMoreElements();) {
-+            String s = (String) e.nextElement();
-+            c.setProperty(s, props.getProperty(s));
-+        }
-+
-+        return c;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/Factory.java
-@@ -0,0 +1,44 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines a functor interface implemented by classes that create objects.
-+ * <p/>
-+ * A <code>Factory</code> creates an object without using an input parameter.
-+ * If an input parameter is required, then {@link Transformer} is more appropriate.
-+ * <p/>
-+ * Standard implementations of common factories are provided by
-+ * {@link FactoryUtils}. These include factories that return a constant,
-+ * a copy of a prototype or a new instance.
-+ *
-+ * @author Arron Bates
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public interface Factory <T> {
-+
-+    /**
-+     * Create a new object.
-+     *
-+     * @return a new object
-+     * @throws FunctorException (runtime) if the factory cannot create an object
-+     */
-+    public T create();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/FactoryUtils.java
-@@ -0,0 +1,135 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.functors.ConstantFactory;
-+import org.apache.commons.collections15.functors.ExceptionFactory;
-+import org.apache.commons.collections15.functors.InstantiateFactory;
-+import org.apache.commons.collections15.functors.PrototypeFactory;
-+
-+/**
-+ * <code>FactoryUtils</code> provides reference implementations and utilities
-+ * for the Factory functor interface. The supplied factories are:
-+ * <ul>
-+ * <li>Prototype - clones a specified object
-+ * <li>Reflection - creates objects using reflection
-+ * <li>Constant - always returns the same object
-+ * <li>Null - always returns null
-+ * <li>Exception - always throws an exception
-+ * </ul>
-+ * All the supplied factories are Serializable.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class FactoryUtils {
-+
-+    /**
-+     * This class is not normally instantiated.
-+     */
-+    public FactoryUtils() {
-+        super();
-+    }
-+
-+    /**
-+     * Gets a Factory that always throws an exception.
-+     * This could be useful during testing as a placeholder.
-+     *
-+     * @return the factory
-+     * @see org.apache.commons.collections15.functors.ExceptionFactory
-+     */
-+    public static Factory exceptionFactory() {
-+        return ExceptionFactory.INSTANCE;
-+    }
-+
-+    /**
-+     * Gets a Factory that will return null each time the factory is used.
-+     * This could be useful during testing as a placeholder.
-+     *
-+     * @return the factory
-+     * @see org.apache.commons.collections15.functors.ConstantFactory
-+     */
-+    public static Factory nullFactory() {
-+        return ConstantFactory.NULL_INSTANCE;
-+    }
-+
-+    /**
-+     * Creates a Factory that will return the same object each time the factory
-+     * is used. No check is made that the object is immutable. In general, only
-+     * immutable objects should use the constant factory. Mutable objects should
-+     * use the prototype factory.
-+     *
-+     * @param constantToReturn the constant object to return each time in the factory
-+     * @return the <code>constant</code> factory.
-+     * @see org.apache.commons.collections15.functors.ConstantFactory
-+     */
-+    public static <T> Factory<T> constantFactory(T constantToReturn) {
-+        return ConstantFactory.getInstance(constantToReturn);
-+    }
-+
-+    /**
-+     * Creates a Factory that will return a clone of the same prototype object
-+     * each time the factory is used. The prototype will be cloned using one of these
-+     * techniques (in order):
-+     * <ul>
-+     * <li>public clone method
-+     * <li>public copy constructor
-+     * <li>serialization clone
-+     * <ul>
-+     *
-+     * @param prototype the object to clone each time in the factory
-+     * @return the <code>prototype</code> factory
-+     * @throws IllegalArgumentException if the prototype is null
-+     * @throws IllegalArgumentException if the prototype cannot be cloned
-+     * @see org.apache.commons.collections15.functors.PrototypeFactory
-+     */
-+    public static <T> Factory<T> prototypeFactory(T prototype) {
-+        return PrototypeFactory.getInstance(prototype);
-+    }
-+
-+    /**
-+     * Creates a Factory that can create objects of a specific type using
-+     * a no-args constructor.
-+     *
-+     * @param classToInstantiate the Class to instantiate each time in the factory
-+     * @return the <code>reflection</code> factory
-+     * @throws IllegalArgumentException if the classToInstantiate is null
-+     * @see org.apache.commons.collections15.functors.InstantiateFactory
-+     */
-+    public static <T> Factory<T> instantiateFactory(Class<T> classToInstantiate) {
-+        return InstantiateFactory.getInstance(classToInstantiate, null, null);
-+    }
-+
-+    /**
-+     * Creates a Factory that can create objects of a specific type using
-+     * the arguments specified to this method.
-+     *
-+     * @param classToInstantiate the Class to instantiate each time in the factory
-+     * @param paramTypes         parameter types for the constructor, can be null
-+     * @param args               the arguments to pass to the constructor, can be null
-+     * @return the <code>reflection</code> factory
-+     * @throws IllegalArgumentException if the classToInstantiate is null
-+     * @throws IllegalArgumentException if the paramTypes and args don't match
-+     * @throws IllegalArgumentException if the constructor doesn't exist
-+     * @see org.apache.commons.collections15.functors.InstantiateFactory
-+     */
-+    public static <T> Factory<T> instantiateFactory(Class<T> classToInstantiate, Class[] paramTypes, Object[] args) {
-+        return InstantiateFactory.getInstance(classToInstantiate, paramTypes, args);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/FunctorException.java
-@@ -0,0 +1,143 @@
-+// GenericsNote: No conversion needed.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.io.PrintStream;
-+import java.io.PrintWriter;
-+
-+/**
-+ * Runtime exception thrown from functors.
-+ * If required, a root cause error can be wrapped within this one.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class FunctorException extends RuntimeException {
-+
-+    /**
-+     * Does JDK support nested exceptions
-+     */
-+    private static final boolean JDK_SUPPORTS_NESTED;
-+
-+    static {
-+        boolean flag = false;
-+        try {
-+            Throwable.class.getDeclaredMethod("getCause", new Class[0]);
-+            flag = true;
-+        } catch (NoSuchMethodException ex) {
-+            flag = false;
-+        }
-+        JDK_SUPPORTS_NESTED = flag;
-+    }
-+
-+    /**
-+     * Root cause of the exception
-+     */
-+    private final Throwable rootCause;
-+
-+    /**
-+     * Constructs a new <code>FunctorException</code> without specified
-+     * detail message.
-+     */
-+    public FunctorException() {
-+        super();
-+        this.rootCause = null;
-+    }
-+
-+    /**
-+     * Constructs a new <code>FunctorException</code> with specified
-+     * detail message.
-+     *
-+     * @param msg the error message.
-+     */
-+    public FunctorException(String msg) {
-+        super(msg);
-+        this.rootCause = null;
-+    }
-+
-+    /**
-+     * Constructs a new <code>FunctorException</code> with specified
-+     * nested <code>Throwable</code> root cause.
-+     *
-+     * @param rootCause the exception or error that caused this exception
-+     *                  to be thrown.
-+     */
-+    public FunctorException(Throwable rootCause) {
-+        super((rootCause == null ? null : rootCause.getMessage()));
-+        this.rootCause = rootCause;
-+    }
-+
-+    /**
-+     * Constructs a new <code>FunctorException</code> with specified
-+     * detail message and nested <code>Throwable</code> root cause.
-+     *
-+     * @param msg       the error message.
-+     * @param rootCause the exception or error that caused this exception
-+     *                  to be thrown.
-+     */
-+    public FunctorException(String msg, Throwable rootCause) {
-+        super(msg);
-+        this.rootCause = rootCause;
-+    }
-+
-+    /**
-+     * Gets the cause of this throwable.
-+     *
-+     * @return the cause of this throwable, or <code>null</code>
-+     */
-+    public Throwable getCause() {
-+        return rootCause;
-+    }
-+
-+    /**
-+     * Prints the stack trace of this exception to the standard error stream.
-+     */
-+    public void printStackTrace() {
-+        printStackTrace(System.err);
-+    }
-+
-+    /**
-+     * Prints the stack trace of this exception to the specified stream.
-+     *
-+     * @param out the <code>PrintStream</code> to use for output
-+     */
-+    public void printStackTrace(PrintStream out) {
-+        synchronized (out) {
-+            PrintWriter pw = new PrintWriter(out, false);
-+            printStackTrace(pw);
-+            // Flush the PrintWriter before it's GC'ed.
-+            pw.flush();
-+        }
-+    }
-+
-+    /**
-+     * Prints the stack trace of this exception to the specified writer.
-+     *
-+     * @param out the <code>PrintWriter</code> to use for output
-+     */
-+    public void printStackTrace(PrintWriter out) {
-+        synchronized (out) {
-+            super.printStackTrace(out);
-+            if (rootCause != null && JDK_SUPPORTS_NESTED == false) {
-+                out.print("Caused by: ");
-+                rootCause.printStackTrace(out);
-+            }
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/IterableMap.java
-@@ -0,0 +1,61 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Map;
-+
-+/**
-+ * Defines a map that can be iterated directly without needing to create an entry set.
-+ * <p/>
-+ * A map iterator is an efficient way of iterating over maps.
-+ * There is no need to access the entry set or cast to Map Entry objects.
-+ * <pre>
-+ * IterableMap map = new HashedMap();
-+ * MapIterator it = map.mapIterator();
-+ * while (it.hasNext()) {
-+ *   Object key = it.next();
-+ *   Object value = it.getValue();
-+ *   it.setValue("newValue");
-+ * }
-+ * </pre>
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface IterableMap <K,V> extends Map<K, V> {
-+
-+    /**
-+     * Obtains a <code>MapIterator</code> over the map.
-+     * <p/>
-+     * A map iterator is an efficient way of iterating over maps.
-+     * There is no need to access the entry set or cast to Map Entry objects.
-+     * <pre>
-+     * IterableMap map = new HashedMap();
-+     * MapIterator it = map.mapIterator();
-+     * while (it.hasNext()) {
-+     *   Object key = it.next();
-+     *   Object value = it.getValue();
-+     *   it.setValue("newValue");
-+     * }
-+     * </pre>
-+     *
-+     * @return a map iterator
-+     */
-+    MapIterator<K, V> mapIterator();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/IteratorUtils.java
-@@ -0,0 +1,863 @@
-+// GenericsNote: Converted, although getIterator(Object) is unsatisfying.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.iterators.*;
-+
-+import java.lang.reflect.Array;
-+import java.lang.reflect.Method;
-+import java.util.*;
-+
-+/**
-+ * Provides static utility methods and decorators for {@link Iterator}
-+ * instances. The implementations are provided in the iterators subpackage.
-+ * <p/>
-+ * WARNING: Due to human error certain binary incompatabilities were introduced
-+ * between Commons Collections 2.1 and 3.0. The class remained source and test
-+ * compatible, so if you can recompile all your classes and dependencies
-+ * everything is OK. Those methods which are binary incompatible are marked as
-+ * such, together with alternate solutions that are binary compatible
-+ * against versions 2.1.1 and 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Phil Steitz
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public class IteratorUtils {
-+    // validation is done in this class in certain cases because the
-+    // public classes allow invalid states
-+
-+    /**
-+     * An iterator over no elements.
-+     * <p/>
-+     * WARNING: This constant is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>EmptyIterator.INSTANCE</code> for compatability with Commons Collections 2.1.1.
-+     */
-+    public static final ResettableIterator EMPTY_ITERATOR = EmptyIterator.RESETTABLE_INSTANCE;
-+    /**
-+     * A list iterator over no elements.
-+     * <p/>
-+     * WARNING: This constant is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>EmptyListIterator.INSTANCE</code> for compatability with Commons Collections 2.1.1.
-+     */
-+    public static final ResettableListIterator EMPTY_LIST_ITERATOR = EmptyListIterator.RESETTABLE_INSTANCE;
-+    /**
-+     * An ordered iterator over no elements.
-+     */
-+    public static final OrderedIterator EMPTY_ORDERED_ITERATOR = EmptyOrderedIterator.INSTANCE;
-+    /**
-+     * A map iterator over no elements.
-+     */
-+    public static final MapIterator EMPTY_MAP_ITERATOR = EmptyMapIterator.INSTANCE;
-+    /**
-+     * An ordered map iterator over no elements.
-+     */
-+    public static final OrderedMapIterator EMPTY_ORDERED_MAP_ITERATOR = EmptyOrderedMapIterator.INSTANCE;
-+
-+    /**
-+     * IteratorUtils is not normally instantiated.
-+     */
-+    public IteratorUtils() {
-+    }
-+
-+    // Empty
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an empty iterator.
-+     * <p/>
-+     * This iterator is a valid iterator object that will iterate over
-+     * nothing.
-+     * <p/>
-+     * WARNING: This method is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>EmptyIterator.INSTANCE</code> for compatability with Commons Collections 2.1.1.
-+     *
-+     * @return an iterator over nothing
-+     */
-+    public static ResettableIterator emptyIterator() {
-+        return EMPTY_ITERATOR;
-+    }
-+
-+    /**
-+     * Gets an empty list iterator.
-+     * <p/>
-+     * This iterator is a valid list iterator object that will iterate
-+     * over nothing.
-+     * <p/>
-+     * WARNING: This method is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>EmptyListIterator.INSTANCE</code> for compatability with Commons Collections 2.1.1.
-+     *
-+     * @return a list iterator over nothing
-+     */
-+    public static ResettableListIterator emptyListIterator() {
-+        return EMPTY_LIST_ITERATOR;
-+    }
-+
-+    /**
-+     * Gets an empty ordered iterator.
-+     * <p/>
-+     * This iterator is a valid iterator object that will iterate
-+     * over nothing.
-+     *
-+     * @return an ordered iterator over nothing
-+     */
-+    public static OrderedIterator emptyOrderedIterator() {
-+        return EMPTY_ORDERED_ITERATOR;
-+    }
-+
-+    /**
-+     * Gets an empty map iterator.
-+     * <p/>
-+     * This iterator is a valid map iterator object that will iterate
-+     * over nothing.
-+     *
-+     * @return a map iterator over nothing
-+     */
-+    public static MapIterator emptyMapIterator() {
-+        return EMPTY_MAP_ITERATOR;
-+    }
-+
-+    /**
-+     * Gets an empty ordered map iterator.
-+     * <p/>
-+     * This iterator is a valid map iterator object that will iterate
-+     * over nothing.
-+     *
-+     * @return a map iterator over nothing
-+     */
-+    public static OrderedMapIterator emptyOrderedMapIterator() {
-+        return EMPTY_ORDERED_MAP_ITERATOR;
-+    }
-+
-+    // Singleton
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets a singleton iterator.
-+     * <p/>
-+     * This iterator is a valid iterator object that will iterate over
-+     * the specified object.
-+     * <p/>
-+     * WARNING: This method is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>new SingletonIterator(object)</code> for compatability.
-+     *
-+     * @param object the single object over which to iterate
-+     * @return a singleton iterator over the object
-+     */
-+    public static <E> ResettableIterator<E> singletonIterator(E object) {
-+        return new SingletonIterator<E>(object);
-+    }
-+
-+    /**
-+     * Gets a singleton list iterator.
-+     * <p/>
-+     * This iterator is a valid list iterator object that will iterate over
-+     * the specified object.
-+     *
-+     * @param object the single object over which to iterate
-+     * @return a singleton list iterator over the object
-+     */
-+    public static <E> ListIterator<E> singletonListIterator(E object) {
-+        return new SingletonListIterator<E>(object);
-+    }
-+
-+    // Arrays
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator over an object array.
-+     * <p/>
-+     * WARNING: This method is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>new ArrayIterator(array)</code> for compatability.
-+     *
-+     * @param array the array over which to iterate
-+     * @return an iterator over the array
-+     * @throws NullPointerException if array is null
-+     */
-+    public static <E> ResettableIterator<E> arrayIterator(E[] array) {
-+        return new ObjectArrayIterator<E>(array);
-+    }
-+
-+    /**
-+     * Gets an iterator over an object or primitive array.
-+     * <p/>
-+     * This method will handle primitive arrays as well as object arrays.
-+     * The primitives will be wrapped in the appropriate wrapper class.
-+     *
-+     * @param array the array over which to iterate
-+     * @return an iterator over the array
-+     * @throws IllegalArgumentException if the array is not an array
-+     * @throws NullPointerException     if array is null
-+     */
-+    public static <E> ResettableIterator<E> arrayIterator(Object array) {
-+        return new ArrayIterator<E>(array);
-+    }
-+
-+    /**
-+     * Gets an iterator over the end part of an object array.
-+     * <p/>
-+     * WARNING: This method is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>new ArrayIterator(array,start)</code> for compatability.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @return an iterator over part of the array
-+     * @throws IndexOutOfBoundsException if start is less than zero or greater
-+     *                                   than the length of the array
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableIterator<E> arrayIterator(E[] array, int start) {
-+        return new ObjectArrayIterator<E>(array, start);
-+    }
-+
-+    /**
-+     * Gets an iterator over the end part of an object or primitive array.
-+     * <p/>
-+     * This method will handle primitive arrays as well as object arrays.
-+     * The primitives will be wrapped in the appropriate wrapper class.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @return an iterator over part of the array
-+     * @throws IllegalArgumentException  if the array is not an array
-+     * @throws IndexOutOfBoundsException if start is less than zero or greater
-+     *                                   than the length of the array
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableIterator<E> arrayIterator(Object array, int start) {
-+        return new ArrayIterator<E>(array, start);
-+    }
-+
-+    /**
-+     * Gets an iterator over part of an object array.
-+     * <p/>
-+     * WARNING: This method is binary incompatible with Commons Collections 2.1 and 2.1.1.
-+     * Use <code>new ArrayIterator(array,start,end)</code> for compatability.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @param end   the index to finish iterating at
-+     * @return an iterator over part of the array
-+     * @throws IndexOutOfBoundsException if array bounds are invalid
-+     * @throws IllegalArgumentException  if end is before start
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableIterator<E> arrayIterator(E[] array, int start, int end) {
-+        return new ObjectArrayIterator<E>(array, start, end);
-+    }
-+
-+    /**
-+     * Gets an iterator over part of an object or primitive array.
-+     * <p/>
-+     * This method will handle primitive arrays as well as object arrays.
-+     * The primitives will be wrapped in the appropriate wrapper class.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @param end   the index to finish iterating at
-+     * @return an iterator over part of the array
-+     * @throws IllegalArgumentException  if the array is not an array
-+     * @throws IndexOutOfBoundsException if array bounds are invalid
-+     * @throws IllegalArgumentException  if end is before start
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableIterator<E> arrayIterator(Object array, int start, int end) {
-+        return new ArrayIterator<E>(array, start, end);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets a list iterator over an object array.
-+     *
-+     * @param array the array over which to iterate
-+     * @return a list iterator over the array
-+     * @throws NullPointerException if array is null
-+     */
-+    public static <E> ResettableListIterator<E> arrayListIterator(E[] array) {
-+        return new ObjectArrayListIterator(array);
-+    }
-+
-+    /**
-+     * Gets a list iterator over an object or primitive array.
-+     * <p/>
-+     * This method will handle primitive arrays as well as object arrays.
-+     * The primitives will be wrapped in the appropriate wrapper class.
-+     *
-+     * @param array the array over which to iterate
-+     * @return a list iterator over the array
-+     * @throws IllegalArgumentException if the array is not an array
-+     * @throws NullPointerException     if array is null
-+     */
-+    public static <E> ResettableListIterator<E> arrayListIterator(Object array) {
-+        return new ArrayListIterator<E>(array);
-+    }
-+
-+    /**
-+     * Gets a list iterator over the end part of an object array.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @return a list iterator over part of the array
-+     * @throws IndexOutOfBoundsException if start is less than zero
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableListIterator<E> arrayListIterator(E[] array, int start) {
-+        return new ObjectArrayListIterator<E>(array, start);
-+    }
-+
-+    /**
-+     * Gets a list iterator over the end part of an object or primitive array.
-+     * <p/>
-+     * This method will handle primitive arrays as well as object arrays.
-+     * The primitives will be wrapped in the appropriate wrapper class.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @return a list iterator over part of the array
-+     * @throws IllegalArgumentException  if the array is not an array
-+     * @throws IndexOutOfBoundsException if start is less than zero
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableListIterator<E> arrayListIterator(Object array, int start) {
-+        return new ArrayListIterator<E>(array, start);
-+    }
-+
-+    /**
-+     * Gets a list iterator over part of an object array.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @param end   the index to finish iterating at
-+     * @return a list iterator over part of the array
-+     * @throws IndexOutOfBoundsException if array bounds are invalid
-+     * @throws IllegalArgumentException  if end is before start
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableListIterator<E> arrayListIterator(E[] array, int start, int end) {
-+        return new ObjectArrayListIterator<E>(array, start, end);
-+    }
-+
-+    /**
-+     * Gets a list iterator over part of an object or primitive array.
-+     * <p/>
-+     * This method will handle primitive arrays as well as object arrays.
-+     * The primitives will be wrapped in the appropriate wrapper class.
-+     *
-+     * @param array the array over which to iterate
-+     * @param start the index to start iterating at
-+     * @param end   the index to finish iterating at
-+     * @return a list iterator over part of the array
-+     * @throws IllegalArgumentException  if the array is not an array
-+     * @throws IndexOutOfBoundsException if array bounds are invalid
-+     * @throws IllegalArgumentException  if end is before start
-+     * @throws NullPointerException      if array is null
-+     */
-+    public static <E> ResettableListIterator<E> arrayListIterator(Object array, int start, int end) {
-+        return new ArrayListIterator<E>(array, start, end);
-+    }
-+    
-+    // Unmodifiable
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an immutable version of an {@link Iterator}. The returned object
-+     * will always throw an {@link UnsupportedOperationException} for
-+     * the {@link Iterator#remove} method.
-+     *
-+     * @param iterator the iterator to make immutable
-+     * @return an immutable version of the iterator
-+     */
-+    public static <E> Iterator<E> unmodifiableIterator(Iterator<E> iterator) {
-+        return UnmodifiableIterator.decorate(iterator);
-+    }
-+
-+    /**
-+     * Gets an immutable version of a {@link ListIterator}. The returned object
-+     * will always throw an {@link UnsupportedOperationException} for
-+     * the {@link Iterator#remove}, {@link ListIterator#add} and
-+     * {@link ListIterator#set} methods.
-+     *
-+     * @param listIterator the iterator to make immutable
-+     * @return an immutable version of the iterator
-+     */
-+    public static <E> ListIterator<E> unmodifiableListIterator(ListIterator<E> listIterator) {
-+        return UnmodifiableListIterator.decorate(listIterator);
-+    }
-+
-+    /**
-+     * Gets an immutable version of a {@link MapIterator}. The returned object
-+     * will always throw an {@link UnsupportedOperationException} for
-+     * the {@link Iterator#remove}, {@link MapIterator#setValue(Object)} methods.
-+     *
-+     * @param mapIterator the iterator to make immutable
-+     * @return an immutable version of the iterator
-+     */
-+    public static <K,V> MapIterator<K, V> unmodifiableMapIterator(MapIterator<K, V> mapIterator) {
-+        return UnmodifiableMapIterator.decorate(mapIterator);
-+    }
-+
-+    // Chained
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator that iterates through two {@link Iterator}s
-+     * one after another.
-+     *
-+     * @param iterator1 the first iterators to use, not null
-+     * @param iterator2 the first iterators to use, not null
-+     * @return a combination iterator over the iterators
-+     * @throws NullPointerException if either iterator is null
-+     */
-+    public static <E> Iterator<E> chainedIterator(Iterator<E> iterator1, Iterator<E> iterator2) {
-+        return new IteratorChain<E>(iterator1, iterator2);
-+    }
-+
-+    /**
-+     * Gets an iterator that iterates through an array of {@link Iterator}s
-+     * one after another.
-+     *
-+     * @param iterators the iterators to use, not null or empty or contain nulls
-+     * @return a combination iterator over the iterators
-+     * @throws NullPointerException if iterators array is null or contains a null
-+     */
-+    public static <E> Iterator<E> chainedIterator(Iterator<E>[] iterators) {
-+        return new IteratorChain<E>(iterators);
-+    }
-+
-+    /**
-+     * Gets an iterator that iterates through a collections15 of {@link Iterator}s
-+     * one after another.
-+     *
-+     * @param iterators the iterators to use, not null or empty or contain nulls
-+     * @return a combination iterator over the iterators
-+     * @throws NullPointerException if iterators collection is null or contains a null
-+     * @throws ClassCastException   if the iterators collection contains the wrong object type
-+     */
-+    public static <E> Iterator<E> chainedIterator(Collection<Iterator<? extends E>> iterators) {
-+        return new IteratorChain<E>(iterators);
-+    }
-+
-+    // Collated
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator that provides an ordered iteration over the elements
-+     * contained in a collection of ordered {@link Iterator}s.
-+     * <p/>
-+     * Given two ordered {@link Iterator}s <code>A</code> and <code>B</code>,
-+     * the {@link Iterator#next()} method will return the lesser of
-+     * <code>A.next()</code> and <code>B.next()</code>.
-+     * <p/>
-+     * The comparator is optional. If null is specified then natural order is used.
-+     *
-+     * @param comparator the comparator to use, may be null for natural order
-+     * @param iterator1  the first iterators to use, not null
-+     * @param iterator2  the first iterators to use, not null
-+     * @return a combination iterator over the iterators
-+     * @throws NullPointerException if either iterator is null
-+     */
-+    public static <E> Iterator<E> collatedIterator(Comparator<? super E> comparator, Iterator<? extends E> iterator1, Iterator<? extends E> iterator2) {
-+        return new CollatingIterator<E>(comparator, iterator1, iterator2);
-+    }
-+
-+    /**
-+     * Gets an iterator that provides an ordered iteration over the elements
-+     * contained in an array of {@link Iterator}s.
-+     * <p/>
-+     * Given two ordered {@link Iterator}s <code>A</code> and <code>B</code>,
-+     * the {@link Iterator#next()} method will return the lesser of
-+     * <code>A.next()</code> and <code>B.next()</code> and so on.
-+     * <p/>
-+     * The comparator is optional. If null is specified then natural order is used.
-+     *
-+     * @param comparator the comparator to use, may be null for natural order
-+     * @param iterators  the iterators to use, not null or empty or contain nulls
-+     * @return a combination iterator over the iterators
-+     * @throws NullPointerException if iterators array is null or contains a null
-+     */
-+    public static <E> Iterator<E> collatedIterator(Comparator<? super E> comparator, Iterator<? extends E>[] iterators) {
-+        return new CollatingIterator<E>(comparator, iterators);
-+    }
-+
-+    /**
-+     * Gets an iterator that provides an ordered iteration over the elements
-+     * contained in a collection of {@link Iterator}s.
-+     * <p/>
-+     * Given two ordered {@link Iterator}s <code>A</code> and <code>B</code>,
-+     * the {@link Iterator#next()} method will return the lesser of
-+     * <code>A.next()</code> and <code>B.next()</code> and so on.
-+     * <p/>
-+     * The comparator is optional. If null is specified then natural order is used.
-+     *
-+     * @param comparator the comparator to use, may be null for natural order
-+     * @param iterators  the iterators to use, not null or empty or contain nulls
-+     * @return a combination iterator over the iterators
-+     * @throws NullPointerException if iterators collection is null or contains a null
-+     * @throws ClassCastException   if the iterators collection contains the wrong object type
-+     */
-+    public static <E> Iterator<E> collatedIterator(Comparator<? super E> comparator, Collection<Iterator<? extends E>> iterators) {
-+        return new CollatingIterator<E>(comparator, iterators);
-+    }
-+    
-+    // Object Graph
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator that operates over an object graph.
-+     * <p/>
-+     * This iterator can extract multiple objects from a complex tree-like object graph.
-+     * The iteration starts from a single root object.
-+     * It uses a <code>Transformer</code> to extract the iterators and elements.
-+     * Its main benefit is that no intermediate <code>List</code> is created.
-+     * <p/>
-+     * For example, consider an object graph:
-+     * <pre>
-+     *                 |- Branch -- Leaf
-+     *                 |         \- Leaf
-+     *         |- Tree |         /- Leaf
-+     *         |       |- Branch -- Leaf
-+     *  Forest |                 \- Leaf
-+     *         |       |- Branch -- Leaf
-+     *         |       |         \- Leaf
-+     *         |- Tree |         /- Leaf
-+     *                 |- Branch -- Leaf
-+     *                 |- Branch -- Leaf</pre>
-+     * The following <code>Transformer</code>, used in this class, will extract all
-+     * the Leaf objects without creating a combined intermediate list:
-+     * <pre>
-+     * public Object transform(Object input) {
-+     *   if (input instanceof Forest) {
-+     *     return ((Forest) input).treeIterator();
-+     *   }
-+     *   if (input instanceof Tree) {
-+     *     return ((Tree) input).branchIterator();
-+     *   }
-+     *   if (input instanceof Branch) {
-+     *     return ((Branch) input).leafIterator();
-+     *   }
-+     *   if (input instanceof Leaf) {
-+     *     return input;
-+     *   }
-+     *   throw new ClassCastException();
-+     * }</pre>
-+     * <p/>
-+     * Internally, iteration starts from the root object. When next is called,
-+     * the transformer is called to examine the object. The transformer will return
-+     * either an iterator or an object. If the object is an Iterator, the next element
-+     * from that iterator is obtained and the process repeats. If the element is an object
-+     * it is returned.
-+     * <p/>
-+     * Under many circumstances, linking Iterators together in this manner is
-+     * more efficient (and convenient) than using nested for loops to extract a list.
-+     *
-+     * @param root        the root object to start iterating from, null results in an empty iterator
-+     * @param transformer the transformer to use, see above, null uses no effect transformer
-+     * @return a new object graph iterator
-+     * @since Commons Collections 3.1
-+     */
-+    public static Iterator objectGraphIterator(Object root, Transformer transformer) {
-+        return new ObjectGraphIterator(root, transformer);
-+    }
-+    
-+    // Transformed
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator that transforms the elements of another iterator.
-+     * <p/>
-+     * The transformation occurs during the next() method and the underlying
-+     * iterator is unaffected by the transformation.
-+     *
-+     * @param iterator  the iterator to use, not null
-+     * @param transform the transform to use, not null
-+     * @return a new transforming iterator
-+     * @throws NullPointerException if either parameter is null
-+     */
-+    public static <I,O> Iterator<O> transformedIterator(Iterator<I> iterator, Transformer<I, O> transform) {
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        if (transform == null) {
-+            throw new NullPointerException("Transformer must not be null");
-+        }
-+        return new TransformIterator<I, O>(iterator, transform);
-+    }
-+    
-+    // Filtered
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator that filters another iterator.
-+     * <p/>
-+     * The returned iterator will only return objects that match the specified
-+     * filtering predicate.
-+     *
-+     * @param iterator  the iterator to use, not null
-+     * @param predicate the predicate to use as a filter, not null
-+     * @return a new filtered iterator
-+     * @throws NullPointerException if either parameter is null
-+     */
-+    public static <E> Iterator<E> filteredIterator(Iterator<E> iterator, Predicate<? super E> predicate) {
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        if (predicate == null) {
-+            throw new NullPointerException("Predicate must not be null");
-+        }
-+        return new FilterIterator<E>(iterator, predicate);
-+    }
-+
-+    /**
-+     * Gets a list iterator that filters another list iterator.
-+     * <p/>
-+     * The returned iterator will only return objects that match the specified
-+     * filtering predicate.
-+     *
-+     * @param listIterator the list iterator to use, not null
-+     * @param predicate    the predicate to use as a filter, not null
-+     * @return a new filtered iterator
-+     * @throws NullPointerException if either parameter is null
-+     */
-+    public static <E> ListIterator<E> filteredListIterator(ListIterator<E> listIterator, Predicate<? super E> predicate) {
-+        if (listIterator == null) {
-+            throw new NullPointerException("ListIterator must not be null");
-+        }
-+        if (predicate == null) {
-+            throw new NullPointerException("Predicate must not be null");
-+        }
-+        return new FilterListIterator<E>(listIterator, predicate);
-+    }
-+    
-+    // Looping
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator that loops continuously over the supplied collection.
-+     * <p/>
-+     * The iterator will only stop looping if the remove method is called
-+     * enough times to empty the collection, or if the collection is empty
-+     * to start with.
-+     *
-+     * @param coll the collection to iterate over, not null
-+     * @return a new looping iterator
-+     * @throws NullPointerException if the collection is null
-+     */
-+    public static <E> ResettableIterator<E> loopingIterator(Collection<E> coll) {
-+        if (coll == null) {
-+            throw new NullPointerException("Collection must not be null");
-+        }
-+        return new LoopingIterator<E>(coll);
-+    }
-+    
-+    // Views
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator that provides an iterator view of the given enumeration.
-+     *
-+     * @param enumeration the enumeration to use
-+     * @return a new iterator
-+     */
-+    public static <E> Iterator<E> asIterator(Enumeration<E> enumeration) {
-+        if (enumeration == null) {
-+            throw new NullPointerException("Enumeration must not be null");
-+        }
-+        return new EnumerationIterator<E>(enumeration);
-+    }
-+
-+    /**
-+     * Gets an iterator that provides an iterator view of the given enumeration
-+     * that will remove elements from the specified collection.
-+     *
-+     * @param enumeration      the enumeration to use
-+     * @param removeCollection the collection to remove elements from
-+     * @return a new iterator
-+     */
-+    public static <E> Iterator<E> asIterator(Enumeration<E> enumeration, Collection<E> removeCollection) {
-+        if (enumeration == null) {
-+            throw new NullPointerException("Enumeration must not be null");
-+        }
-+        if (removeCollection == null) {
-+            throw new NullPointerException("Collection must not be null");
-+        }
-+        return new EnumerationIterator<E>(enumeration, removeCollection);
-+    }
-+
-+    /**
-+     * Gets an enumeration that wraps an iterator.
-+     *
-+     * @param iterator the iterator to use, not null
-+     * @return a new enumeration
-+     * @throws NullPointerException if iterator is null
-+     */
-+    public static <E> Enumeration<E> asEnumeration(Iterator<E> iterator) {
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        return new IteratorEnumeration<E>(iterator);
-+    }
-+
-+    /**
-+     * Gets a list iterator based on a simple iterator.
-+     * <p/>
-+     * As the wrapped Iterator is traversed, a LinkedList of its values is
-+     * cached, permitting all required operations of ListIterator.
-+     *
-+     * @param iterator the iterator to use, not null
-+     * @return a new iterator
-+     * @throws NullPointerException if iterator parameter is null
-+     */
-+    public static <E> ListIterator<E> toListIterator(Iterator<E> iterator) {
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        return new ListIteratorWrapper<E>(iterator);
-+    }
-+
-+    /**
-+     * Gets an array based on an iterator.
-+     * <p/>
-+     * As the wrapped Iterator is traversed, an ArrayList of its values is
-+     * created. At the end, this is converted to an array.
-+     *
-+     * @param iterator the iterator to use, not null
-+     * @return an array of the iterator contents
-+     * @throws NullPointerException if iterator parameter is null
-+     */
-+    public static <E> E[] toArray(Iterator<E> iterator) {
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        List<E> list = toList(iterator, 100);
-+        return (E[]) list.toArray();
-+    }
-+
-+    /**
-+     * Gets an array based on an iterator.
-+     * <p/>
-+     * As the wrapped Iterator is traversed, an ArrayList of its values is
-+     * created. At the end, this is converted to an array.
-+     *
-+     * @param iterator   the iterator to use, not null
-+     * @param arrayClass the class of array to create
-+     * @return an array of the iterator contents
-+     * @throws NullPointerException if iterator parameter is null
-+     * @throws NullPointerException if arrayClass is null
-+     * @throws ClassCastException   if the arrayClass is invalid
-+     */
-+    public static <E> E[] toArray(Iterator<E> iterator, Class<E> arrayClass) {
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        if (arrayClass == null) {
-+            throw new NullPointerException("Array class must not be null");
-+        }
-+        List<E> list = toList(iterator, 100);
-+        return list.toArray((E[]) Array.newInstance(arrayClass, list.size()));
-+    }
-+
-+    /**
-+     * Gets a list based on an iterator.
-+     * <p/>
-+     * As the wrapped Iterator is traversed, an ArrayList of its values is
-+     * created. At the end, the list is returned.
-+     *
-+     * @param iterator the iterator to use, not null
-+     * @return a list of the iterator contents
-+     * @throws NullPointerException if iterator parameter is null
-+     */
-+    public static <E> List<E> toList(Iterator<E> iterator) {
-+        return toList(iterator, 10);
-+    }
-+
-+    /**
-+     * Gets a list based on an iterator.
-+     * <p/>
-+     * As the wrapped Iterator is traversed, an ArrayList of its values is
-+     * created. At the end, the list is returned.
-+     *
-+     * @param iterator      the iterator to use, not null
-+     * @param estimatedSize the initial size of the ArrayList
-+     * @return a list of the iterator contents
-+     * @throws NullPointerException     if iterator parameter is null
-+     * @throws IllegalArgumentException if the size is less than 1
-+     */
-+    public static <E> List<E> toList(Iterator<E> iterator, int estimatedSize) {
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        if (estimatedSize < 1) {
-+            throw new IllegalArgumentException("Estimated size must be greater than 0");
-+        }
-+        List<E> list = new ArrayList<E>(estimatedSize);
-+        while (iterator.hasNext()) {
-+            list.add(iterator.next());
-+        }
-+        return list;
-+    }
-+
-+    /**
-+     * Gets a suitable Iterator for the given object.
-+     * <p/>
-+     * This method can handles objects as follows
-+     * <ul>
-+     * <li>null - empty iterator
-+     * <li>Iterator - returned directly
-+     * <li>Enumeration - wrapped
-+     * <li>Collection - iterator from collection returned
-+     * <li>Map - values iterator returned
-+     * <li>Dictionary - values (elements) enumeration returned as iterator
-+     * <li>array - iterator over array returned
-+     * <li>object with iterator() public method accessed by reflection
-+     * <li>object - singleton iterator
-+     * </ul>
-+     *
-+     * @param obj the object to convert to an iterator
-+     * @return a suitable iterator, never null
-+     */
-+    public static Iterator getIterator(Object obj) {
-+        if (obj == null) {
-+            return emptyIterator();
-+
-+        } else if (obj instanceof Iterator) {
-+            return (Iterator) obj;
-+
-+        } else if (obj instanceof Collection) {
-+            return ((Collection) obj).iterator();
-+
-+        } else if (obj instanceof Object[]) {
-+            return new ObjectArrayIterator((Object[]) obj);
-+
-+        } else if (obj instanceof Enumeration) {
-+            return new EnumerationIterator((Enumeration) obj);
-+
-+        } else if (obj instanceof Map) {
-+            return ((Map) obj).values().iterator();
-+
-+        } else if (obj instanceof Dictionary) {
-+            return new EnumerationIterator(((Dictionary) obj).elements());
-+
-+        } else if (obj != null && obj.getClass().isArray()) {
-+            return new ArrayIterator(obj);
-+
-+        } else {
-+            try {
-+                Method method = obj.getClass().getMethod("iterator", null);
-+                if (Iterator.class.isAssignableFrom(method.getReturnType())) {
-+                    Iterator it = (Iterator) method.invoke(obj, null);
-+                    if (it != null) {
-+                        return it;
-+                    }
-+                }
-+            } catch (Exception ex) {
-+                // ignore
-+            }
-+            return singletonIterator(obj);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/KeyValue.java
-@@ -0,0 +1,46 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines a simple key value pair.
-+ * <p/>
-+ * A Map Entry has considerable additional semantics over and above a simple
-+ * key-value pair. This interface defines the minimum key value, with just the
-+ * two get methods.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface KeyValue <K,V> {
-+
-+    /**
-+     * Gets the key from the pair.
-+     *
-+     * @return the key
-+     */
-+    K getKey();
-+
-+    /**
-+     * Gets the value from the pair.
-+     *
-+     * @return the value
-+     */
-+    V getValue();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/ListUtils.java
-@@ -0,0 +1,345 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.list.*;
-+
-+import java.util.*;
-+
-+/**
-+ * Provides utility methods and decorators for {@link List} instances.
-+ *
-+ * @author Federico Barbieri
-+ * @author Peter Donald
-+ * @author Paul Jack
-+ * @author Stephen Colebourne
-+ * @author Neil O'Toole
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public class ListUtils {
-+
-+    /**
-+     * An empty unmodifiable list.
-+     * This uses the {@link Collections Collections} implementation
-+     * and is provided for completeness.
-+     */
-+    public static final List EMPTY_LIST = Collections.EMPTY_LIST;
-+
-+    /**
-+     * <code>ListUtils</code> should not normally be instantiated.
-+     */
-+    public ListUtils() {
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a new list containing all elements that are contained in
-+     * both given lists.
-+     *
-+     * @param list1 the first list
-+     * @param list2 the second list
-+     * @return the intersection of those two lists
-+     * @throws NullPointerException if either list is null
-+     */
-+    public static <E> List<E> intersection(final List<? extends E> list1, final List<? extends E> list2) {
-+        final ArrayList<E> result = new ArrayList<E>();
-+        final Iterator<? extends E> iterator = list2.iterator();
-+
-+        while (iterator.hasNext()) {
-+            final E o = iterator.next();
-+
-+            if (list1.contains(o)) {
-+                result.add(o);
-+            }
-+        }
-+
-+        return result;
-+    }
-+
-+    /**
-+     * Subtracts all elements in the second list from the first list,
-+     * placing the results in a new list.
-+     * <p/>
-+     * This differs from {@link List#removeAll(Collection)} in that
-+     * cardinality is respected; if <Code>list1</Code> contains two
-+     * occurrences of <Code>null</Code> and <Code>list2</Code> only
-+     * contains one occurrence, then the returned list will still contain
-+     * one occurrence.
-+     *
-+     * @param list1 the list to subtract from
-+     * @param list2 the list to subtract
-+     * @return a new list containing the results
-+     * @throws NullPointerException if either list is null
-+     */
-+    public static <E> List<E> subtract(final List<? extends E> list1, final List<? extends E> list2) {
-+        final ArrayList<E> result = new ArrayList<E>(list1);
-+        final Iterator<? extends E> iterator = list2.iterator();
-+
-+        while (iterator.hasNext()) {
-+            result.remove(iterator.next());
-+        }
-+
-+        return result;
-+    }
-+
-+    /**
-+     * Returns the sum of the given lists.  This is their intersection
-+     * subtracted from their union.
-+     *
-+     * @param list1 the first list
-+     * @param list2 the second list
-+     * @return a new list containing the sum of those lists
-+     * @throws NullPointerException if either list is null
-+     */
-+    public static <E> List<E> sum(final List<? extends E> list1, final List<? extends E> list2) {
-+        return subtract(union(list1, list2), intersection(list1, list2));
-+    }
-+
-+    /**
-+     * Returns a new list containing the second list appended to the
-+     * first list.  The {@link List#addAll(Collection)} operation is
-+     * used to append the two given lists into a new list.
-+     *
-+     * @param list1 the first list
-+     * @param list2 the second list
-+     * @return a new list containing the union of those lists
-+     * @throws NullPointerException if either list is null
-+     */
-+    public static <E> List<E> union(final List<? extends E> list1, final List<? extends E> list2) {
-+        final ArrayList<E> result = new ArrayList<E>(list1);
-+        result.addAll(list2);
-+        return result;
-+    }
-+
-+    /**
-+     * Tests two lists for value-equality as per the equality contract in
-+     * {@link java.util.List#equals(java.lang.Object)}.
-+     * <p/>
-+     * This method is useful for implementing <code>List</code> when you cannot
-+     * extend AbstractList. The method takes Collection instances to enable other
-+     * collection types to use the List implementation algorithm.
-+     * <p/>
-+     * The relevant text (slightly paraphrased as this is a static method) is:
-+     * <blockquote>
-+     * Compares the two list objects for equality.  Returns
-+     * <tt>true</tt> if and only if both
-+     * lists have the same size, and all corresponding pairs of elements in
-+     * the two lists are <i>equal</i>.  (Two elements <tt>e1</tt> and
-+     * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
-+     * e1.equals(e2))</tt>.)  In other words, two lists are defined to be
-+     * equal if they contain the same elements in the same order.  This
-+     * definition ensures that the equals method works properly across
-+     * different implementations of the <tt>List</tt> interface.
-+     * </blockquote>
-+     * <p/>
-+     * <b>Note:</b> The behaviour of this method is undefined if the lists are
-+     * modified during the equals comparison.
-+     *
-+     * @param list1 the first list, may be null
-+     * @param list2 the second list, may be null
-+     * @return whether the lists are equal by value comparison
-+     * @see java.util.List
-+     */
-+    public static <E> boolean isEqualList(final Collection<? extends E> list1, final Collection<? extends E> list2) {
-+        if (list1 == list2) {
-+            return true;
-+        }
-+        if (list1 == null || list2 == null || list1.size() != list2.size()) {
-+            return false;
-+        }
-+
-+        Iterator<? extends E> it1 = list1.iterator();
-+        Iterator<? extends E> it2 = list2.iterator();
-+        E obj1 = null;
-+        E obj2 = null;
-+
-+        while (it1.hasNext() && it2.hasNext()) {
-+            obj1 = it1.next();
-+            obj2 = it2.next();
-+
-+            if (!(obj1 == null ? obj2 == null : obj1.equals(obj2))) {
-+                return false;
-+            }
-+        }
-+
-+        return !(it1.hasNext() || it2.hasNext());
-+    }
-+
-+    /**
-+     * Generates a hash code using the algorithm specified in
-+     * {@link java.util.List#hashCode()}.
-+     * <p/>
-+     * This method is useful for implementing <code>List</code> when you cannot
-+     * extend AbstractList. The method takes Collection instances to enable other
-+     * collection types to use the List implementation algorithm.
-+     *
-+     * @param list the list to generate the hashCode for, may be null
-+     * @return the hash code
-+     * @see java.util.List#hashCode()
-+     */
-+    public static int hashCodeForList(final Collection list) {
-+        if (list == null) {
-+            return 0;
-+        }
-+        int hashCode = 1;
-+        Iterator it = list.iterator();
-+        Object obj = null;
-+
-+        while (it.hasNext()) {
-+            obj = it.next();
-+            hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
-+        }
-+        return hashCode;
-+    }   
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized list backed by the given list.
-+     * <p/>
-+     * You must manually synchronize on the returned buffer's iterator to
-+     * avoid non-deterministic behavior:
-+     * <p/>
-+     * <pre>
-+     * List list = ListUtils.synchronizedList(myList);
-+     * synchronized (list) {
-+     *     Iterator i = list.iterator();
-+     *     while (i.hasNext()) {
-+     *         process (i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param list the list to synchronize, must not be null
-+     * @return a synchronized list backed by the given list
-+     * @throws IllegalArgumentException if the list is null
-+     */
-+    public static <E> List<E> synchronizedList(List<E> list) {
-+        return SynchronizedList.decorate(list);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable list backed by the given list.
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param list the list to make unmodifiable, must not be null
-+     * @return an unmodifiable list backed by the given list
-+     * @throws IllegalArgumentException if the list is null
-+     */
-+    public static <E> List<E> unmodifiableList(List<E> list) {
-+        return UnmodifiableList.decorate(list);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) list backed by the given list.
-+     * <p/>
-+     * Only objects that pass the test in the given predicate can be added to the list.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * It is important not to use the original list after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param list      the list to predicate, must not be null
-+     * @param predicate the predicate for the list, must not be null
-+     * @return a predicated list backed by the given list
-+     * @throws IllegalArgumentException if the List or Predicate is null
-+     */
-+    public static <E> List<E> predicatedList(List<E> list, Predicate<? super E> predicate) {
-+        return PredicatedList.decorate(list, predicate);
-+    }
-+
-+    /**
-+     * Returns a typed list backed by the given list.
-+     * <p/>
-+     * Only objects of the specified type can be added to the list.
-+     *
-+     * @param list the list to limit to a specific type, must not be null
-+     * @param type the type of objects which may be added to the list
-+     * @return a typed list backed by the specified list
-+     * @deprecated Java generics makes this method obsolete.
-+     */
-+    public static <E> List<E> typedList(List<E> list, Class<E> type) {
-+        return TypedList.decorate(list, type);
-+    }
-+
-+    /**
-+     * Returns a transformed list backed by the given list.
-+     * <p/>
-+     * Each object is passed through the transformer as it is added to the
-+     * List. It is important not to use the original list after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param list        the list to predicate, must not be null
-+     * @param transformer the transformer for the list, must not be null
-+     * @return a transformed list backed by the given list
-+     * @throws IllegalArgumentException if the List or Transformer is null
-+     */
-+    public static <I,O> List<O> transformedList(List<I> list, Transformer<? super I, ? extends O> transformer) {
-+        return TransformedList.decorate(list, transformer);
-+    }
-+
-+    /**
-+     * Returns a "lazy" list whose elements will be created on demand.
-+     * <p/>
-+     * When the index passed to the returned list's {@link List#get(int) get}
-+     * method is greater than the list's size, then the factory will be used
-+     * to create a new object and that object will be inserted at that index.
-+     * <p/>
-+     * For instance:
-+     * <p/>
-+     * <pre>
-+     * Factory factory = new Factory() {
-+     *     public Object create() {
-+     *         return new Date();
-+     *     }
-+     * }
-+     * List lazy = ListUtils.lazyList(new ArrayList(), factory);
-+     * Object obj = lazy.get(3);
-+     * </pre>
-+     * <p/>
-+     * After the above code is executed, <code>obj</code> will contain
-+     * a new <code>Date</code> instance.  Furthermore, that <code>Date</code>
-+     * instance is the fourth element in the list.  The first, second,
-+     * and third element are all set to <code>null</code>.
-+     *
-+     * @param list    the list to make lazy, must not be null
-+     * @param factory the factory for creating new objects, must not be null
-+     * @return a lazy list backed by the given list
-+     * @throws IllegalArgumentException if the List or Factory is null
-+     */
-+    public static <E> List<E> lazyList(List<E> list, Factory<? extends E> factory) {
-+        return LazyList.decorate(list, factory);
-+    }
-+
-+    /**
-+     * Returns a fixed-sized list backed by the given list.
-+     * Elements may not be added or removed from the returned list, but
-+     * existing elements can be changed (for instance, via the
-+     * {@link List#set(int,Object)} method).
-+     *
-+     * @param list the list whose size to fix, must not be null
-+     * @return a fixed-size list backed by that list
-+     * @throws IllegalArgumentException if the List is null
-+     */
-+    public static <E> List<E> fixedSizeList(List<E> list) {
-+        return FixedSizeList.decorate(list);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/MapIterator.java
-@@ -0,0 +1,109 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * Defines an iterator that operates over a <code>Map</code>.
-+ * <p/>
-+ * This iterator is a special version designed for maps. It can be more
-+ * efficient to use this rather than an entry set iterator where the option
-+ * is available, and it is certainly more convenient.
-+ * <p/>
-+ * A map that provides this interface may not hold the data internally using
-+ * Map Entry objects, thus this interface can avoid lots of object creation.
-+ * <p/>
-+ * In use, this iterator iterates through the keys in the map. After each call
-+ * to <code>next()</code>, the <code>getValue()</code> method provides direct
-+ * access to the value. The value can also be set using <code>setValue()</code>.
-+ * <pre>
-+ * MapIterator it = map.mapIterator();
-+ * while (it.hasNext()) {
-+ *   Object key = it.next();
-+ *   Object value = it.getValue();
-+ *   it.setValue(newValue);
-+ * }
-+ * </pre>
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface MapIterator <K,V> extends Iterator<K> {
-+
-+    /**
-+     * Checks to see if there are more entries still to be iterated.
-+     *
-+     * @return <code>true</code> if the iterator has more elements
-+     */
-+    boolean hasNext();
-+
-+    /**
-+     * Gets the next <em>key</em> from the <code>Map</code>.
-+     *
-+     * @return the next key in the iteration
-+     * @throws java.util.NoSuchElementException
-+     *          if the iteration is finished
-+     */
-+    K next();
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the current key, which is the key returned by the last call
-+     * to <code>next()</code>.
-+     *
-+     * @return the current key
-+     * @throws IllegalStateException if <code>next()</code> has not yet been called
-+     */
-+    K getKey();
-+
-+    /**
-+     * Gets the current value, which is the value associated with the last key
-+     * returned by <code>next()</code>.
-+     *
-+     * @return the current value
-+     * @throws IllegalStateException if <code>next()</code> has not yet been called
-+     */
-+    V getValue();
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Removes the last returned key from the underlying <code>Map</code> (optional operation).
-+     * <p/>
-+     * This method can be called once per call to <code>next()</code>.
-+     *
-+     * @throws UnsupportedOperationException if remove is not supported by the map
-+     * @throws IllegalStateException         if <code>next()</code> has not yet been called
-+     * @throws IllegalStateException         if <code>remove()</code> has already been called
-+     *                                       since the last call to <code>next()</code>
-+     */
-+    void remove();
-+
-+    /**
-+     * Sets the value associated with the current key (optional operation).
-+     *
-+     * @param value the new value
-+     * @return the previous value
-+     * @throws UnsupportedOperationException if setValue is not supported by the map
-+     * @throws IllegalStateException         if <code>next()</code> has not yet been called
-+     * @throws IllegalStateException         if <code>remove()</code> has been called since the
-+     *                                       last call to <code>next()</code>
-+     */
-+    V setValue(V value);
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/MapUtils.java
-@@ -0,0 +1,1354 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.map.*;
-+
-+import java.io.PrintStream;
-+import java.text.NumberFormat;
-+import java.text.ParseException;
-+import java.util.*;
-+
-+/**
-+ * Provides utility methods and decorators for
-+ * {@link Map} and {@link SortedMap} instances.
-+ * <p/>
-+ * It contains various type safe methods
-+ * as well as other useful features like deep copying.
-+ * <p/>
-+ * It also provides the following decorators:
-+ * <p/>
-+ * <ul>
-+ * <li>{@link #fixedSizeMap(Map)}
-+ * <li>{@link #fixedSizeSortedMap(SortedMap)}
-+ * <li>{@link #lazyMap(Map,Factory)}
-+ * <li>{@link #lazySortedMap(SortedMap,Factory)}
-+ * <li>{@link #predicatedMap(Map,Predicate,Predicate)}
-+ * <li>{@link #predicatedSortedMap(SortedMap,Predicate,Predicate)}
-+ * <li>{@link #transformedMap(Map, Transformer, Transformer)}
-+ * <li>{@link #transformedSortedMap(SortedMap, Transformer, Transformer)}
-+ * <li>{@link #typedMap(Map, Class, Class)}
-+ * <li>{@link #typedSortedMap(SortedMap, Class, Class)}
-+ * </ul>
-+ *
-+ * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
-+ * @author <a href="mailto:nissim at nksystems.com">Nissim Karpenstein</a>
-+ * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
-+ * @author Paul Jack
-+ * @author Stephen Colebourne
-+ * @author Matthew Hawthorne
-+ * @author Arun Mammen Thomas
-+ * @author Janek Bogucki
-+ * @author Max Rydahl Andersen
-+ * @author Matt Hall, John Watkinson, <a href="mailto:equinus100 at hotmail.com">Ashwin S</a>
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public class MapUtils {
-+
-+    /**
-+     * An empty unmodifiable map.
-+     * This was not provided in JDK1.2.
-+     */
-+    public static final Map EMPTY_MAP = UnmodifiableMap.decorate(new HashMap(1));
-+    /**
-+     * An empty unmodifiable sorted map.
-+     * This is not provided in the JDK.
-+     */
-+    public static final SortedMap EMPTY_SORTED_MAP = UnmodifiableSortedMap.decorate(new TreeMap());
-+    /**
-+     * String used to indent the verbose and debug Map prints.
-+     */
-+    private static final String INDENT_STRING = "    ";
-+
-+    /**
-+     * <code>MapUtils</code> should not normally be instantiated.
-+     */
-+    public MapUtils() {
-+    }    
-+    
-+    // Type safe getters
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Gets from a Map in a null-safe manner.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map, <code>null</code> if null map input
-+     */
-+    public static <K,V> V getObject(final Map<K, V> map, final K key) {
-+        if (map != null) {
-+            return map.get(key);
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets a String from a Map in a null-safe manner.
-+     * <p/>
-+     * The String is obtained via <code>toString</code>.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a String, <code>null</code> if null map input
-+     */
-+    public static <K,V> String getString(final Map<K, V> map, final K key) {
-+        if (map != null) {
-+            V answer = map.get(key);
-+            if (answer != null) {
-+                return answer.toString();
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets a Boolean from a Map in a null-safe manner.
-+     * <p/>
-+     * If the value is a <code>Boolean</code> it is returned directly.
-+     * If the value is a <code>String</code> and it equals 'true' ignoring case
-+     * then <code>true</code> is returned, otherwise <code>false</code>.
-+     * If the value is a <code>Number</code> an integer zero value returns
-+     * <code>false</code> and non-zero returns <code>true</code>.
-+     * Otherwise, <code>null</code> is returned.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Boolean, <code>null</code> if null map input
-+     */
-+    public static Boolean getBoolean(final Map map, final Object key) {
-+        if (map != null) {
-+            Object answer = map.get(key);
-+            if (answer != null) {
-+                if (answer instanceof Boolean) {
-+                    return (Boolean) answer;
-+
-+                } else if (answer instanceof String) {
-+                    return new Boolean((String) answer);
-+
-+                } else if (answer instanceof Number) {
-+                    Number n = (Number) answer;
-+                    return (n.intValue() != 0) ? Boolean.TRUE : Boolean.FALSE;
-+                }
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets a Number from a Map in a null-safe manner.
-+     * <p/>
-+     * If the value is a <code>Number</code> it is returned directly.
-+     * If the value is a <code>String</code> it is converted using
-+     * {@link NumberFormat#parse(String)} on the system default formatter
-+     * returning <code>null</code> if the conversion fails.
-+     * Otherwise, <code>null</code> is returned.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Number, <code>null</code> if null map input
-+     */
-+    public static Number getNumber(final Map map, final Object key) {
-+        if (map != null) {
-+            Object answer = map.get(key);
-+            if (answer != null) {
-+                if (answer instanceof Number) {
-+                    return (Number) answer;
-+
-+                } else if (answer instanceof String) {
-+                    try {
-+                        String text = (String) answer;
-+                        return NumberFormat.getInstance().parse(text);
-+
-+                    } catch (ParseException e) {
-+                        logInfo(e);
-+                    }
-+                }
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets a Byte from a Map in a null-safe manner.
-+     * <p/>
-+     * The Byte is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Byte, <code>null</code> if null map input
-+     */
-+    public static Byte getByte(final Map map, final Object key) {
-+        Number answer = getNumber(map, key);
-+        if (answer == null) {
-+            return null;
-+        } else if (answer instanceof Byte) {
-+            return (Byte) answer;
-+        }
-+        return new Byte(answer.byteValue());
-+    }
-+
-+    /**
-+     * Gets a Short from a Map in a null-safe manner.
-+     * <p/>
-+     * The Short is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Short, <code>null</code> if null map input
-+     */
-+    public static Short getShort(final Map map, final Object key) {
-+        Number answer = getNumber(map, key);
-+        if (answer == null) {
-+            return null;
-+        } else if (answer instanceof Short) {
-+            return (Short) answer;
-+        }
-+        return new Short(answer.shortValue());
-+    }
-+
-+    /**
-+     * Gets a Integer from a Map in a null-safe manner.
-+     * <p/>
-+     * The Integer is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Integer, <code>null</code> if null map input
-+     */
-+    public static Integer getInteger(final Map map, final Object key) {
-+        Number answer = getNumber(map, key);
-+        if (answer == null) {
-+            return null;
-+        } else if (answer instanceof Integer) {
-+            return (Integer) answer;
-+        }
-+        return new Integer(answer.intValue());
-+    }
-+
-+    /**
-+     * Gets a Long from a Map in a null-safe manner.
-+     * <p/>
-+     * The Long is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Long, <code>null</code> if null map input
-+     */
-+    public static Long getLong(final Map map, final Object key) {
-+        Number answer = getNumber(map, key);
-+        if (answer == null) {
-+            return null;
-+        } else if (answer instanceof Long) {
-+            return (Long) answer;
-+        }
-+        return new Long(answer.longValue());
-+    }
-+
-+    /**
-+     * Gets a Float from a Map in a null-safe manner.
-+     * <p/>
-+     * The Float is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Float, <code>null</code> if null map input
-+     */
-+    public static Float getFloat(final Map map, final Object key) {
-+        Number answer = getNumber(map, key);
-+        if (answer == null) {
-+            return null;
-+        } else if (answer instanceof Float) {
-+            return (Float) answer;
-+        }
-+        return new Float(answer.floatValue());
-+    }
-+
-+    /**
-+     * Gets a Double from a Map in a null-safe manner.
-+     * <p/>
-+     * The Double is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Double, <code>null</code> if null map input
-+     */
-+    public static Double getDouble(final Map map, final Object key) {
-+        Number answer = getNumber(map, key);
-+        if (answer == null) {
-+            return null;
-+        } else if (answer instanceof Double) {
-+            return (Double) answer;
-+        }
-+        return new Double(answer.doubleValue());
-+    }
-+
-+    /**
-+     * Gets a Map from a Map in a null-safe manner.
-+     * <p/>
-+     * If the value returned from the specified map is not a Map then
-+     * <code>null</code> is returned.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Map, <code>null</code> if null map input
-+     */
-+    public static <K,A,B> Map<A, B> getMap(final Map<K, Map<A, B>> map, final K key) {
-+        if (map != null) {
-+            Map<A, B> answer = map.get(key);
-+            if (answer != null) {
-+                return answer;
-+            }
-+        }
-+        return null;
-+    }
-+
-+    // Type safe getters with default values
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Looks up the given key in the given map, converting null into the
-+     * given default value.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null
-+     * @return the value in the map, or defaultValue if the original value
-+     *         is null or the map is null
-+     */
-+    public static <K,V> V getObject(Map<K, V> map, K key, V defaultValue) {
-+        if (map != null) {
-+            V answer = map.get(key);
-+            if (answer != null) {
-+                return answer;
-+            }
-+        }
-+        return defaultValue;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a string, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a string, or defaultValue if the
-+     *         original value is null, the map is null or the string conversion
-+     *         fails
-+     */
-+    public static String getString(Map map, Object key, String defaultValue) {
-+        String answer = getString(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a boolean, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a boolean, or defaultValue if the
-+     *         original value is null, the map is null or the boolean conversion
-+     *         fails
-+     */
-+    public static Boolean getBoolean(Map map, Object key, Boolean defaultValue) {
-+        Boolean answer = getBoolean(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a number, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the number conversion
-+     *         fails
-+     */
-+    public static Number getNumber(Map map, Object key, Number defaultValue) {
-+        Number answer = getNumber(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a byte, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the number conversion
-+     *         fails
-+     */
-+    public static Byte getByte(Map map, Object key, Byte defaultValue) {
-+        Byte answer = getByte(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a short, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the number conversion
-+     *         fails
-+     */
-+    public static Short getShort(Map map, Object key, Short defaultValue) {
-+        Short answer = getShort(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * an integer, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the number conversion
-+     *         fails
-+     */
-+    public static Integer getInteger(Map map, Object key, Integer defaultValue) {
-+        Integer answer = getInteger(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a long, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the number conversion
-+     *         fails
-+     */
-+    public static Long getLong(Map map, Object key, Long defaultValue) {
-+        Long answer = getLong(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a float, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the number conversion
-+     *         fails
-+     */
-+    public static Float getFloat(Map map, Object key, Float defaultValue) {
-+        Float answer = getFloat(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a double, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the number conversion
-+     *         fails
-+     */
-+    public static Double getDouble(Map map, Object key, Double defaultValue) {
-+        Double answer = getDouble(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Looks up the given key in the given map, converting the result into
-+     * a map, using the default value if the the conversion fails.
-+     *
-+     * @param map          the map whose value to look up
-+     * @param key          the key of the value to look up in that map
-+     * @param defaultValue what to return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the map as a number, or defaultValue if the
-+     *         original value is null, the map is null or the map conversion
-+     *         fails
-+     */
-+    public static <K,A,B> Map<A, B> getMap(Map<K, Map<A, B>> map, K key, Map<A, B> defaultValue) {
-+        Map<A, B> answer = getMap(map, key);
-+        if (answer == null) {
-+            answer = defaultValue;
-+        }
-+        return answer;
-+    }
-+    
-+
-+    // Type safe primitive getters
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Gets a boolean from a Map in a null-safe manner.
-+     * <p/>
-+     * If the value is a <code>Boolean</code> its value is returned.
-+     * If the value is a <code>String</code> and it equals 'true' ignoring case
-+     * then <code>true</code> is returned, otherwise <code>false</code>.
-+     * If the value is a <code>Number</code> an integer zero value returns
-+     * <code>false</code> and non-zero returns <code>true</code>.
-+     * Otherwise, <code>false</code> is returned.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a Boolean, <code>false</code> if null map input
-+     */
-+    public static boolean getBooleanValue(final Map map, final Object key) {
-+        Boolean booleanObject = getBoolean(map, key);
-+        if (booleanObject == null) {
-+            return false;
-+        }
-+        return booleanObject.booleanValue();
-+    }
-+
-+    /**
-+     * Gets a byte from a Map in a null-safe manner.
-+     * <p/>
-+     * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a byte, <code>0</code> if null map input
-+     */
-+    public static byte getByteValue(final Map map, final Object key) {
-+        Byte byteObject = getByte(map, key);
-+        if (byteObject == null) {
-+            return 0;
-+        }
-+        return byteObject.byteValue();
-+    }
-+
-+    /**
-+     * Gets a short from a Map in a null-safe manner.
-+     * <p/>
-+     * The short is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a short, <code>0</code> if null map input
-+     */
-+    public static short getShortValue(final Map map, final Object key) {
-+        Short shortObject = getShort(map, key);
-+        if (shortObject == null) {
-+            return 0;
-+        }
-+        return shortObject.shortValue();
-+    }
-+
-+    /**
-+     * Gets an int from a Map in a null-safe manner.
-+     * <p/>
-+     * The int is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as an int, <code>0</code> if null map input
-+     */
-+    public static int getIntValue(final Map map, final Object key) {
-+        Integer integerObject = getInteger(map, key);
-+        if (integerObject == null) {
-+            return 0;
-+        }
-+        return integerObject.intValue();
-+    }
-+
-+    /**
-+     * Gets a long from a Map in a null-safe manner.
-+     * <p/>
-+     * The long is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a long, <code>0L</code> if null map input
-+     */
-+    public static long getLongValue(final Map map, final Object key) {
-+        Long longObject = getLong(map, key);
-+        if (longObject == null) {
-+            return 0L;
-+        }
-+        return longObject.longValue();
-+    }
-+
-+    /**
-+     * Gets a float from a Map in a null-safe manner.
-+     * <p/>
-+     * The float is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a float, <code>0.0F</code> if null map input
-+     */
-+    public static float getFloatValue(final Map map, final Object key) {
-+        Float floatObject = getFloat(map, key);
-+        if (floatObject == null) {
-+            return 0f;
-+        }
-+        return floatObject.floatValue();
-+    }
-+
-+    /**
-+     * Gets a double from a Map in a null-safe manner.
-+     * <p/>
-+     * The double is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map the map to use
-+     * @param key the key to look up
-+     * @return the value in the Map as a double, <code>0.0</code> if null map input
-+     */
-+    public static double getDoubleValue(final Map map, final Object key) {
-+        Double doubleObject = getDouble(map, key);
-+        if (doubleObject == null) {
-+            return 0d;
-+        }
-+        return doubleObject.doubleValue();
-+    }
-+
-+    // Type safe primitive getters with default values
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Gets a boolean from a Map in a null-safe manner,
-+     * using the default value if the the conversion fails.
-+     * <p/>
-+     * If the value is a <code>Boolean</code> its value is returned.
-+     * If the value is a <code>String</code> and it equals 'true' ignoring case
-+     * then <code>true</code> is returned, otherwise <code>false</code>.
-+     * If the value is a <code>Number</code> an integer zero value returns
-+     * <code>false</code> and non-zero returns <code>true</code>.
-+     * Otherwise, <code>defaultValue</code> is returned.
-+     *
-+     * @param map          the map to use
-+     * @param key          the key to look up
-+     * @param defaultValue return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the Map as a Boolean, <code>defaultValue</code> if null map input
-+     */
-+    public static boolean getBooleanValue(final Map map, final Object key, boolean defaultValue) {
-+        Boolean booleanObject = getBoolean(map, key);
-+        if (booleanObject == null) {
-+            return defaultValue;
-+        }
-+        return booleanObject.booleanValue();
-+    }
-+
-+    /**
-+     * Gets a byte from a Map in a null-safe manner,
-+     * using the default value if the the conversion fails.
-+     * <p/>
-+     * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map          the map to use
-+     * @param key          the key to look up
-+     * @param defaultValue return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the Map as a byte, <code>defaultValue</code> if null map input
-+     */
-+    public static byte getByteValue(final Map map, final Object key, byte defaultValue) {
-+        Byte byteObject = getByte(map, key);
-+        if (byteObject == null) {
-+            return defaultValue;
-+        }
-+        return byteObject.byteValue();
-+    }
-+
-+    /**
-+     * Gets a short from a Map in a null-safe manner,
-+     * using the default value if the the conversion fails.
-+     * <p/>
-+     * The short is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map          the map to use
-+     * @param key          the key to look up
-+     * @param defaultValue return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the Map as a short, <code>defaultValue</code> if null map input
-+     */
-+    public static short getShortValue(final Map map, final Object key, short defaultValue) {
-+        Short shortObject = getShort(map, key);
-+        if (shortObject == null) {
-+            return defaultValue;
-+        }
-+        return shortObject.shortValue();
-+    }
-+
-+    /**
-+     * Gets an int from a Map in a null-safe manner,
-+     * using the default value if the the conversion fails.
-+     * <p/>
-+     * The int is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map          the map to use
-+     * @param key          the key to look up
-+     * @param defaultValue return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the Map as an int, <code>defaultValue</code> if null map input
-+     */
-+    public static int getIntValue(final Map map, final Object key, int defaultValue) {
-+        Integer integerObject = getInteger(map, key);
-+        if (integerObject == null) {
-+            return defaultValue;
-+        }
-+        return integerObject.intValue();
-+    }
-+
-+    /**
-+     * Gets a long from a Map in a null-safe manner,
-+     * using the default value if the the conversion fails.
-+     * <p/>
-+     * The long is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map          the map to use
-+     * @param key          the key to look up
-+     * @param defaultValue return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the Map as a long, <code>defaultValue</code> if null map input
-+     */
-+    public static long getLongValue(final Map map, final Object key, long defaultValue) {
-+        Long longObject = getLong(map, key);
-+        if (longObject == null) {
-+            return defaultValue;
-+        }
-+        return longObject.longValue();
-+    }
-+
-+    /**
-+     * Gets a float from a Map in a null-safe manner,
-+     * using the default value if the the conversion fails.
-+     * <p/>
-+     * The float is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map          the map to use
-+     * @param key          the key to look up
-+     * @param defaultValue return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the Map as a float, <code>defaultValue</code> if null map input
-+     */
-+    public static float getFloatValue(final Map map, final Object key, float defaultValue) {
-+        Float floatObject = getFloat(map, key);
-+        if (floatObject == null) {
-+            return defaultValue;
-+        }
-+        return floatObject.floatValue();
-+    }
-+
-+    /**
-+     * Gets a double from a Map in a null-safe manner,
-+     * using the default value if the the conversion fails.
-+     * <p/>
-+     * The double is obtained from the results of {@link #getNumber(Map,Object)}.
-+     *
-+     * @param map          the map to use
-+     * @param key          the key to look up
-+     * @param defaultValue return if the value is null or if the
-+     *                     conversion fails
-+     * @return the value in the Map as a double, <code>defaultValue</code> if null map input
-+     */
-+    public static double getDoubleValue(final Map map, final Object key, double defaultValue) {
-+        Double doubleObject = getDouble(map, key);
-+        if (doubleObject == null) {
-+            return defaultValue;
-+        }
-+        return doubleObject.doubleValue();
-+    }
-+
-+    // Conversion methods
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Gets a new Properties object initialised with the values from a Map.
-+     * A null input will return an empty properties object.
-+     *
-+     * @param map the map to convert to a Properties object, may not be null
-+     * @return the properties object
-+     */
-+    public static Properties toProperties(final Map map) {
-+        Properties answer = new Properties();
-+        if (map != null) {
-+            for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
-+                Map.Entry entry = (Map.Entry) iter.next();
-+                Object key = entry.getKey();
-+                Object value = entry.getValue();
-+                answer.put(key, value);
-+            }
-+        }
-+        return answer;
-+    }
-+
-+    /**
-+     * Creates a new HashMap using data copied from a ResourceBundle.
-+     *
-+     * @param resourceBundle the resource bundle to convert, may not be null
-+     * @return the hashmap containing the data
-+     * @throws NullPointerException if the bundle is null
-+     */
-+    public static Map<String, Object> toMap(final ResourceBundle resourceBundle) {
-+        Enumeration<String> enumeration = resourceBundle.getKeys();
-+        Map<String, Object> map = new HashMap<String, Object>();
-+
-+        while (enumeration.hasMoreElements()) {
-+            String key = enumeration.nextElement();
-+            Object value = resourceBundle.getObject(key);
-+            map.put(key, value);
-+        }
-+
-+        return map;
-+    }
-+ 
-+    // Printing methods
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Prints the given map with nice line breaks.
-+     * <p/>
-+     * This method prints a nicely formatted String describing the Map.
-+     * Each map entry will be printed with key and value.
-+     * When the value is a Map, recursive behaviour occurs.
-+     * <p/>
-+     * This method is NOT thread-safe in any special way. You must manually
-+     * synchronize on either this class or the stream as required.
-+     *
-+     * @param out   the stream to print to, must not be null
-+     * @param label The label to be used, may be <code>null</code>.
-+     *              If <code>null</code>, the label is not output.
-+     *              It typically represents the name of the property in a bean or similar.
-+     * @param map   The map to print, may be <code>null</code>.
-+     *              If <code>null</code>, the text 'null' is output.
-+     * @throws NullPointerException if the stream is <code>null</code>
-+     */
-+    public static void verbosePrint(final PrintStream out, final Object label, final Map map) {
-+
-+        verbosePrintInternal(out, label, map, new ArrayStack(), false);
-+    }
-+
-+    /**
-+     * Prints the given map with nice line breaks.
-+     * <p/>
-+     * This method prints a nicely formatted String describing the Map.
-+     * Each map entry will be printed with key, value and value classname.
-+     * When the value is a Map, recursive behaviour occurs.
-+     * <p/>
-+     * This method is NOT thread-safe in any special way. You must manually
-+     * synchronize on either this class or the stream as required.
-+     *
-+     * @param out   the stream to print to, must not be null
-+     * @param label The label to be used, may be <code>null</code>.
-+     *              If <code>null</code>, the label is not output.
-+     *              It typically represents the name of the property in a bean or similar.
-+     * @param map   The map to print, may be <code>null</code>.
-+     *              If <code>null</code>, the text 'null' is output.
-+     * @throws NullPointerException if the stream is <code>null</code>
-+     */
-+    public static void debugPrint(final PrintStream out, final Object label, final Map map) {
-+
-+        verbosePrintInternal(out, label, map, new ArrayStack(), true);
-+    }
-+
-+    // Implementation methods
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Logs the given exception to <code>System.out</code>.
-+     * <p/>
-+     * This method exists as Jakarta Collections does not depend on logging.
-+     *
-+     * @param ex the exception to log
-+     */
-+    protected static void logInfo(final Exception ex) {
-+        System.out.println("INFO: Exception: " + ex);
-+    }
-+
-+    /**
-+     * Implementation providing functionality for {@link #debugPrint} and for
-+     * {@link #verbosePrint}.  This prints the given map with nice line breaks.
-+     * If the debug flag is true, it additionally prints the type of the object
-+     * value.  If the contents of a map include the map itself, then the text
-+     * <em>(this Map)</em> is printed out.  If the contents include a
-+     * parent container of the map, the the text <em>(ancestor[i] Map)</em> is
-+     * printed, where i actually indicates the number of levels which must be
-+     * traversed in the sequential list of ancestors (e.g. father, grandfather,
-+     * great-grandfather, etc).
-+     *
-+     * @param out     the stream to print to
-+     * @param label   the label to be used, may be <code>null</code>.
-+     *                If <code>null</code>, the label is not output.
-+     *                It typically represents the name of the property in a bean or similar.
-+     * @param map     the map to print, may be <code>null</code>.
-+     *                If <code>null</code>, the text 'null' is output
-+     * @param lineage a stack consisting of any maps in which the previous
-+     *                argument is contained. This is checked to avoid infinite recursion when
-+     *                printing the output
-+     * @param debug   flag indicating whether type names should be output.
-+     * @throws NullPointerException if the stream is <code>null</code>
-+     */
-+    private static void verbosePrintInternal(final PrintStream out, final Object label, final Map map, final ArrayStack lineage, final boolean debug) {
-+
-+        printIndent(out, lineage.size());
-+
-+        if (map == null) {
-+            if (label != null) {
-+                out.print(label);
-+                out.print(" = ");
-+            }
-+            out.println("null");
-+            return;
-+        }
-+        if (label != null) {
-+            out.print(label);
-+            out.println(" = ");
-+        }
-+
-+        printIndent(out, lineage.size());
-+        out.println("{");
-+
-+        lineage.push(map);
-+
-+        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            Object childKey = entry.getKey();
-+            Object childValue = entry.getValue();
-+            if (childValue instanceof Map && !lineage.contains(childValue)) {
-+                verbosePrintInternal(out, (childKey == null ? "null" : childKey), (Map) childValue, lineage, debug);
-+            } else {
-+                printIndent(out, lineage.size());
-+                out.print(childKey);
-+                out.print(" = ");
-+
-+                final int lineageIndex = lineage.indexOf(childValue);
-+                if (lineageIndex == -1) {
-+                    out.print(childValue);
-+                } else if (lineage.size() - 1 == lineageIndex) {
-+                    out.print("(this Map)");
-+                } else {
-+                    out.print("(ancestor[" + (lineage.size() - 1 - lineageIndex - 1) + "] Map)");
-+                }
-+
-+                if (debug && childValue != null) {
-+                    out.print(' ');
-+                    out.println(childValue.getClass().getName());
-+                } else {
-+                    out.println();
-+                }
-+            }
-+        }
-+
-+        lineage.pop();
-+
-+        printIndent(out, lineage.size());
-+        out.println(debug ? "} " + map.getClass().getName() : "}");
-+    }
-+
-+    /**
-+     * Writes indentation to the given stream.
-+     *
-+     * @param out the stream to indent
-+     */
-+    private static void printIndent(final PrintStream out, final int indent) {
-+        for (int i = 0; i < indent; i++) {
-+            out.print(INDENT_STRING);
-+        }
-+    }
-+    
-+    // Misc
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inverts the supplied map returning a new HashMap such that the keys of
-+     * the input are swapped with the values.
-+     * <p/>
-+     * This operation assumes that the inverse mapping is well defined.
-+     * If the input map had multiple entries with the same value mapped to
-+     * different keys, the returned map will map one of those keys to the
-+     * value, but the exact key which will be mapped is undefined.
-+     *
-+     * @param map the map to invert, may not be null
-+     * @return a new HashMap containing the inverted data
-+     * @throws NullPointerException if the map is null
-+     */
-+    public static <K,V> Map<V, K> invertMap(Map<K, V> map) {
-+        Map<V, K> out = new HashMap<V, K>(map.size());
-+        for (Iterator<Map.Entry<K, V>> it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<K, V> entry = it.next();
-+            out.put(entry.getValue(), entry.getKey());
-+        }
-+        return out;
-+    }
-+
-+    /**
-+     * Nice method for adding data to a map in such a way
-+     * as to not get NPE's. The point being that if the
-+     * value is null, map.put() will throw an exception.
-+     * That blows in the case of this class cause you may want to
-+     * essentially treat put("Not Null", null ) == put("Not Null", "")
-+     * We will still throw a NPE if the key is null cause that should
-+     * never happen.
-+     * <p>
-+     * Note: this is not a type-safe operation in Java 1.5.
-+     *
-+     * @param map   the map to add to, may not be null
-+     * @param key   the key
-+     * @param value the value
-+     * @throws NullPointerException if the map is null
-+     *
-+     */
-+    public static void safeAddToMap(Map map, Object key, Object value) throws NullPointerException {
-+        if (value == null) {
-+            map.put(key, "");
-+        } else {
-+            map.put(key, value);
-+        }
-+    }
-+
-+    // Map decorators
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized map backed by the given map.
-+     * <p/>
-+     * You must manually synchronize on the returned buffer's iterator to
-+     * avoid non-deterministic behavior:
-+     * <p/>
-+     * <pre>
-+     * Map m = MapUtils.synchronizedMap(myMap);
-+     * Set s = m.keySet();  // outside synchronized block
-+     * synchronized (m) {  // synchronized on MAP!
-+     *     Iterator i = s.iterator();
-+     *     while (i.hasNext()) {
-+     *         process (i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * This method uses the implementation in {@link java.util.Collections Collections}.
-+     *
-+     * @param map the map to synchronize, must not be null
-+     * @return a synchronized map backed by the given map
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    public static <K,V> Map<K, V> synchronizedMap(Map<K, V> map) {
-+        return Collections.synchronizedMap(map);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable map backed by the given map.
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param map the map to make unmodifiable, must not be null
-+     * @return an unmodifiable map backed by the given map
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    public static <K,V> Map<K, V> unmodifiableMap(Map<K, V> map) {
-+        return UnmodifiableMap.decorate(map);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) map backed by the given map.
-+     * <p/>
-+     * Only objects that pass the tests in the given predicates can be added to the map.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * Keys must pass the key predicate, values must pass the value predicate.
-+     * It is important not to use the original map after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param map       the map to predicate, must not be null
-+     * @param keyPred   the predicate for keys, null means no check
-+     * @param valuePred the predicate for values, null means no check
-+     * @return a predicated map backed by the given map
-+     * @throws IllegalArgumentException if the Map is null
-+     */
-+    public static <K,V> Map<K, V> predicatedMap(Map<K, V> map, Predicate<? super K> keyPred, Predicate<? super V> valuePred) {
-+        return PredicatedMap.decorate(map, keyPred, valuePred);
-+    }
-+
-+    /**
-+     * Returns a typed map backed by the given map.
-+     * <p/>
-+     * Only keys and values of the specified types can be added to the map.
-+     *
-+     * @param map       the map to limit to a specific type, must not be null
-+     * @param keyType   the type of keys which may be added to the map, must not be null
-+     * @param valueType the type of values which may be added to the map, must not be null
-+     * @return a typed map backed by the specified map
-+     * @throws IllegalArgumentException if the Map or Class is null
-+     * @deprecated this is no longer needed with Java generics.
-+     */
-+    public static Map typedMap(Map map, Class keyType, Class valueType) {
-+        return TypedMap.decorate(map, keyType, valueType);
-+    }
-+
-+    /**
-+     * Returns a transformed map backed by the given map.
-+     * <p/>
-+     * Each object is passed through the transformers as it is added to the
-+     * Map. It is important not to use the original map after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param map              the map to transform, must not be null
-+     * @param keyTransformer   the transformer for the map keys, null means no transformation
-+     * @param valueTransformer the transformer for the map values, null means no transformation
-+     * @return a transformed map backed by the given map
-+     * @throws IllegalArgumentException if the Map is null
-+     */
-+    public static Map transformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
-+        return TransformedMap.decorate(map, keyTransformer, valueTransformer);
-+    }
-+
-+    /**
-+     * Returns a fixed-sized map backed by the given map.
-+     * Elements may not be added or removed from the returned map, but
-+     * existing elements can be changed (for instance, via the
-+     * {@link Map#put(Object,Object)} method).
-+     *
-+     * @param map the map whose size to fix, must not be null
-+     * @return a fixed-size map backed by that map
-+     * @throws IllegalArgumentException if the Map is null
-+     */
-+    public static <K,V> Map<K, V> fixedSizeMap(Map<K, V> map) {
-+        return FixedSizeMap.decorate(map);
-+    }
-+
-+    /**
-+     * Returns a "lazy" map whose values will be created on demand.
-+     * <p/>
-+     * When the key passed to the returned map's {@link Map#get(Object)}
-+     * method is not present in the map, then the factory will be used
-+     * to create a new object and that object will become the value
-+     * associated with that key.
-+     * <p/>
-+     * For instance:
-+     * <pre>
-+     * Factory factory = new Factory() {
-+     *     public Object create() {
-+     *         return new Date();
-+     *     }
-+     * }
-+     * Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
-+     * Object obj = lazyMap.get("test");
-+     * </pre>
-+     * <p/>
-+     * After the above code is executed, <code>obj</code> will contain
-+     * a new <code>Date</code> instance.  Furthermore, that <code>Date</code>
-+     * instance is the value for the <code>"test"</code> key in the map.
-+     *
-+     * @param map     the map to make lazy, must not be null
-+     * @param factory the factory for creating new objects, must not be null
-+     * @return a lazy map backed by the given map
-+     * @throws IllegalArgumentException if the Map or Factory is null
-+     */
-+    public static <K,V> Map<K, V> lazyMap(Map<K, V> map, Factory<V> factory) {
-+        return LazyMap.decorate(map, factory);
-+    }
-+
-+    /**
-+     * Returns a map that maintains the order of keys that are added
-+     * backed by the given map.
-+     * <p/>
-+     * If a key is added twice, the order is determined by the first add.
-+     * The order is observed through the keySet, values and entrySet.
-+     *
-+     * @param map the map to order, must not be null
-+     * @return an ordered map backed by the given map
-+     * @throws IllegalArgumentException if the Map is null
-+     */
-+    public static <K,V> Map<K, V> orderedMap(Map<K, V> map) {
-+        return ListOrderedMap.decorate(map);
-+    }
-+    
-+    // SortedMap decorators
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized sorted map backed by the given sorted map.
-+     * <p/>
-+     * You must manually synchronize on the returned buffer's iterator to
-+     * avoid non-deterministic behavior:
-+     * <p/>
-+     * <pre>
-+     * Map m = MapUtils.synchronizedSortedMap(myMap);
-+     * Set s = m.keySet();  // outside synchronized block
-+     * synchronized (m) {  // synchronized on MAP!
-+     *     Iterator i = s.iterator();
-+     *     while (i.hasNext()) {
-+     *         process (i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * This method uses the implementation in {@link java.util.Collections Collections}.
-+     *
-+     * @param map the map to synchronize, must not be null
-+     * @return a synchronized map backed by the given map
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    public static <K,V> Map<K, V> synchronizedSortedMap(SortedMap<K, V> map) {
-+        return Collections.synchronizedSortedMap(map);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable sorted map backed by the given sorted map.
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param map the sorted map to make unmodifiable, must not be null
-+     * @return an unmodifiable map backed by the given map
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    public static <K,V> Map<K, V> unmodifiableSortedMap(SortedMap<K, V> map) {
-+        return UnmodifiableSortedMap.decorate(map);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) sorted map backed by the given map.
-+     * <p/>
-+     * Only objects that pass the tests in the given predicates can be added to the map.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * Keys must pass the key predicate, values must pass the value predicate.
-+     * It is important not to use the original map after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param map       the map to predicate, must not be null
-+     * @param keyPred   the predicate for keys, null means no check
-+     * @param valuePred the predicate for values, null means no check
-+     * @return a predicated map backed by the given map
-+     * @throws IllegalArgumentException if the SortedMap is null
-+     */
-+    public static <K,V> SortedMap<K, V> predicatedSortedMap(SortedMap<K, V> map, Predicate<? super K> keyPred, Predicate<? super V> valuePred) {
-+        return PredicatedSortedMap.decorate(map, keyPred, valuePred);
-+    }
-+
-+    /**
-+     * Returns a typed sorted map backed by the given map.
-+     * <p/>
-+     * Only keys and values of the specified types can be added to the map.
-+     *
-+     * @param map       the map to limit to a specific type, must not be null
-+     * @param keyType   the type of keys which may be added to the map, must not be null
-+     * @param valueType the type of values which may be added to the map, must not be null
-+     * @return a typed map backed by the specified map
-+     * @deprecated no longer needed with Java generics.
-+     */
-+    public static SortedMap typedSortedMap(SortedMap map, Class keyType, Class valueType) {
-+        return TypedSortedMap.decorate(map, keyType, valueType);
-+    }
-+
-+    /**
-+     * Returns a transformed sorted map backed by the given map.
-+     * <p/>
-+     * Each object is passed through the transformers as it is added to the
-+     * Map. It is important not to use the original map after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param map              the map to transform, must not be null
-+     * @param keyTransformer   the transformer for the map keys, null means no transformation
-+     * @param valueTransformer the transformer for the map values, null means no transformation
-+     * @return a transformed map backed by the given map
-+     * @throws IllegalArgumentException if the SortedMap is null
-+     */
-+    public static SortedMap transformedSortedMap(SortedMap map, Transformer keyTransformer, Transformer valueTransformer) {
-+        return TransformedSortedMap.decorate(map, keyTransformer, valueTransformer);
-+    }
-+
-+    /**
-+     * Returns a fixed-sized sorted map backed by the given sorted map.
-+     * Elements may not be added or removed from the returned map, but
-+     * existing elements can be changed (for instance, via the
-+     * {@link Map#put(Object,Object)} method).
-+     *
-+     * @param map the map whose size to fix, must not be null
-+     * @return a fixed-size map backed by that map
-+     * @throws IllegalArgumentException if the SortedMap is null
-+     */
-+    public static <K,V> SortedMap<K, V> fixedSizeSortedMap(SortedMap<K, V> map) {
-+        return FixedSizeSortedMap.decorate(map);
-+    }
-+
-+    /**
-+     * Returns a "lazy" sorted map whose values will be created on demand.
-+     * <p/>
-+     * When the key passed to the returned map's {@link Map#get(Object)}
-+     * method is not present in the map, then the factory will be used
-+     * to create a new object and that object will become the value
-+     * associated with that key.
-+     * <p/>
-+     * For instance:
-+     * <p/>
-+     * <pre>
-+     * Factory factory = new Factory() {
-+     *     public Object create() {
-+     *         return new Date();
-+     *     }
-+     * }
-+     * SortedMap lazy = MapUtils.lazySortedMap(new TreeMap(), factory);
-+     * Object obj = lazy.get("test");
-+     * </pre>
-+     * <p/>
-+     * After the above code is executed, <code>obj</code> will contain
-+     * a new <code>Date</code> instance.  Furthermore, that <code>Date</code>
-+     * instance is the value for the <code>"test"</code> key.
-+     *
-+     * @param map     the map to make lazy, must not be null
-+     * @param factory the factory for creating new objects, must not be null
-+     * @return a lazy map backed by the given map
-+     * @throws IllegalArgumentException if the SortedMap or Factory is null
-+     */
-+    public static <K,V> SortedMap<K, V> lazySortedMap(SortedMap<K, V> map, Factory<V> factory) {
-+        return LazySortedMap.decorate(map, factory);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/MultiMap.java
-@@ -0,0 +1,337 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.*;
-+
-+/**
-+ * Defines a map that holds a collection of values against each key.
-+ * <p/>
-+ * A <code>MultiMap</code> is a Map with slightly different semantics.
-+ * Putting a value into the map will add the value to a Collection at that key.
-+ * Getting a value will return a Collection, holding all the values put to that key.
-+ * <p/>
-+ * For example:
-+ * <pre>
-+ * Number key = new Integer(5);
-+ * MultiMap<Number,String> mhm = new MultiHashMap<Number,String>();
-+ * mhm.put(key, "A");
-+ * mhm.put(key, "B");
-+ * mhm.put(key, "C");
-+ * Collection<String> coll = mhm.get(key);</pre>
-+ * <p/>
-+ * <code>coll</code> will be a collection containing "A", "B", "C".
-+ * <p/>
-+ * NOTE: Note: this new, generics-friendly version of the MultiMap interface does
-+ * NOT extend java.util.Map! This is because MultiMap breaks the Map contract in
-+ * too many ways to allow generics support. However, you can get a live java.util.Map
-+ * for a MultiMap with the method {@link #map()}.
-+ *
-+ * @author Christopher Berry
-+ * @author James Strachan
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.0
-+ */
-+public interface MultiMap <K,V> {
-+
-+    /**
-+     * Removes a specific value from map.
-+     * <p/>
-+     * The item is removed from the collection mapped to the specified key.
-+     * Other values attached to that key are unaffected.
-+     * <p/>
-+     * If the last value for a key is removed, implementations typically
-+     * return <code>null</code> from a subsequant <code>get(Object)</code>, however
-+     * they may choose to return an empty collection.
-+     *
-+     * @param key  the key to remove from
-+     * @param item the item to remove
-+     * @return the value removed (which was passed in), null if nothing removed
-+     * @throws UnsupportedOperationException if the map is unmodifiable
-+     * @throws ClassCastException            if the key or value is of an invalid type
-+     * @throws NullPointerException          if the key or value is null and null is invalid
-+     */
-+    public V remove(Object key, Object item);
-+
-+    /**
-+     * Gets the number of values in this map for the given key.
-+     * <p/>
-+     * Implementations return the count of keys in the map, or 0 if there are no values for the given key.
-+     *
-+     * @return the number of values in this map for the given key.
-+     */
-+    int size(Object key);
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the number of keys in this map.
-+     * <p/>
-+     * Implementations return the count of keys in the map.
-+     *
-+     * @return the number of key-collection mappings in this map
-+     */
-+    int size();
-+
-+    /**
-+     * Gets the collection of values associated with the specified key.
-+     * <p/>
-+     * The returned value will implement <code>Collection</code>. Implementations
-+     * are free to declare that they return <code>Collection</code> subclasses
-+     * such as <code>List</code> or <code>Set</code>.
-+     * <p/>
-+     * Implementations return <code>null</code> if no values have
-+     * been mapped to the key.
-+     * <p/>
-+     * Implementations may choose to return a clone of the internal collection.
-+     *
-+     * @param key the key to retrieve
-+     * @return the <code>Collection</code> of values, implementations should
-+     *         return <code>null</code> for no mapping, but may return an empty collection
-+     * @throws ClassCastException   if the key is of an invalid type
-+     * @throws NullPointerException if the key is null and null keys are invalid
-+     */
-+    Collection<V> get(Object key);
-+
-+    /**
-+     * Checks whether the map contains the value specified.
-+     * <p/>
-+     * Implementations check all collections15 against all keys for the value.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the value
-+     * @throws ClassCastException   if the value is of an invalid type
-+     * @throws NullPointerException if the value is null and null value are invalid
-+     */
-+    boolean containsValue(Object value);
-+
-+    /**
-+     * Checks whether the map contains the value specified, at the key specified.
-+     *
-+     * @param value the value to search for
-+     * @param key the key against which to search for the value
-+     * @return true if the map contains the value
-+     * @throws ClassCastException   if the value is of an invalid type
-+     * @throws NullPointerException if the value is null and null value are invalid
-+     */
-+    boolean containsValue(Object key, Object value);
-+
-+    /**
-+     * Adds the value to the collection associated with the specified key.
-+     * <p/>
-+     * Unlike a normal <code>Map</code> the previous value is not replaced.
-+     * Instead the new value is added to the collection stored against the key.
-+     * The collection may be a <code>List</code>, <code>Set</code> or other
-+     * collection dependent on implementation.
-+     *
-+     * @param key   the key to store against
-+     * @param value the value to add to the collection at the key
-+     * @return typically the value added if the map changed and null if the map did not change
-+     * @throws UnsupportedOperationException if the map is unmodifiable
-+     * @throws ClassCastException            if the key or value is of an invalid type
-+     * @throws NullPointerException          if the key or value is null and null is invalid
-+     * @throws IllegalArgumentException      if the key or value is invalid
-+     */
-+    V put(K key, V value);
-+
-+    /**
-+     * Removes all values associated with the specified key.
-+     * <p/>
-+     * Implementations typically return <code>null</code> from a subsequent
-+     * <code>get(Object)</code>, however they may choose to return an empty collection.
-+     *
-+     * @param key the key to remove values from
-+     * @return the <code>Collection</code> of values removed, implementations should
-+     *         return <code>null</code> for no mapping found, but may return an empty collection
-+     * @throws UnsupportedOperationException if the map is unmodifiable
-+     * @throws ClassCastException            if the key is of an invalid type
-+     * @throws NullPointerException          if the key is null and null keys are invalid
-+     */
-+    Collection<V> remove(Object key);
-+
-+    /**
-+     * Gets a collection containing all the values in the map.
-+     * <p/>
-+     * Inplementations return a collection containing the combination
-+     * of values from all keys.
-+     *
-+     * @return a collection view of the values contained in this map
-+     */
-+    Collection<V> values();
-+
-+    /**
-+     * Returns <tt>true</tt> if this map contains no key-value mappings.
-+     *
-+     * @return <tt>true</tt> if this map contains no key-value mappings.
-+     */
-+    boolean isEmpty();
-+
-+    /**
-+     * Returns <tt>true</tt> if this map contains a mapping for the specified
-+     * key.  More formally, returns <tt>true</tt> if and only if
-+     * this map contains a mapping for a key <tt>k</tt> such that
-+     * <tt>(key==null ? k==null : key.equals(k))</tt>.  (There can be
-+     * at most one such mapping.)
-+     *
-+     * @param key key whose presence in this map is to be tested.
-+     * @return <tt>true</tt> if this map contains a mapping for the specified
-+     *         key.
-+     * @throws ClassCastException   if the key is of an inappropriate type for
-+     *                              this map (optional).
-+     * @throws NullPointerException if the key is <tt>null</tt> and this map
-+     *                              does not permit <tt>null</tt> keys (optional).
-+     */
-+    boolean containsKey(Object key);
-+
-+    // Modification Operations
-+
-+    // Bulk Operations
-+
-+    /**
-+     * Copies all of the mappings from the specified map to this map
-+     * (optional operation).  The effect of this call is equivalent to that
-+     * of calling {@link #put(Object,Object) put(k, v)} on this map once
-+     * for each mapping from key <tt>k</tt> to value <tt>v</tt> in the
-+     * specified map.  The behavior of this operation is unspecified if the
-+     * specified map is modified while the operation is in progress.
-+     *
-+     * @param t Mappings to be stored in this map.
-+     * @throws UnsupportedOperationException if the <tt>putAll</tt> method is
-+     *                                       not supported by this map.
-+     * @throws ClassCastException            if the class of a key or value in the
-+     *                                       specified map prevents it from being stored in this map.
-+     * @throws IllegalArgumentException      some aspect of a key or value in the
-+     *                                       specified map prevents it from being stored in this map.
-+     * @throws NullPointerException          if the specified map is <tt>null</tt>, or if
-+     *                                       this map does not permit <tt>null</tt> keys or values, and the
-+     *                                       specified map contains <tt>null</tt> keys or values.
-+     */
-+    void putAll(Map<? extends K, ? extends V> t);
-+
-+    /**
-+     * Copies all of the mappings from the specified multimap to this multimap
-+     * (optional operation).  The effect of this call is equivalent to that
-+     * of calling {@link #put(Object,Object) put(k, v)} on this map once
-+     * for each mapping from key to collections15 of values in the
-+     * specified multimap.  The behavior of this operation is unspecified if the
-+     * specified multimap is modified while the operation is in progress.
-+     *
-+     * @param t Mappings to be stored in this map.
-+     * @throws UnsupportedOperationException if the <tt>putAll</tt> method is
-+     *                                       not supported by this map.
-+     * @throws ClassCastException            if the class of a key or value in the
-+     *                                       specified map prevents it from being stored in this map.
-+     * @throws IllegalArgumentException      some aspect of a key or value in the
-+     *                                       specified map prevents it from being stored in this map.
-+     * @throws NullPointerException          if the specified map is <tt>null</tt>, or if
-+     *                                       this map does not permit <tt>null</tt> keys or values, and the
-+     *                                       specified map contains <tt>null</tt> keys or values.
-+     */
-+    void putAll(MultiMap<? extends K, ? extends V> t);
-+
-+    /**
-+     * Copies all of the values in the given collection in to the multimap against the given key.
-+     * @param key the key against which to store the values.
-+     * @param values the collection of values to map to the key.
-+     */
-+    boolean putAll(K key, Collection<? extends V> values);
-+
-+    Iterator<V> iterator(Object key);
-+
-+    /**
-+     * Removes all mappings from this map (optional operation).
-+     *
-+     * @throws UnsupportedOperationException clear is not supported by this
-+     *                                       map.
-+     */
-+    void clear();
-+
-+
-+    // Views
-+
-+    /**
-+     * Returns a set view of the keys contained in this map.  The set is
-+     * backed by the map, so changes to the map are reflected in the set, and
-+     * vice-versa.  If the map is modified while an iteration over the set is
-+     * in progress (except through the iterator's own <tt>remove</tt>
-+     * operation), the results of the iteration are undefined.  The set
-+     * supports element removal, which removes the corresponding mapping from
-+     * the map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
-+     * <tt>removeAll</tt> <tt>retainAll</tt>, and <tt>clear</tt> operations.
-+     * It does not support the add or <tt>addAll</tt> operations.
-+     *
-+     * @return a set view of the keys contained in this map.
-+     */
-+    Set<K> keySet();
-+
-+    /**
-+     * Returns a set view of the mappings contained in this map.  Each element
-+     * in the returned set is a {@link Map.Entry}.  The set is backed by the
-+     * map, so changes to the map are reflected in the set, and vice-versa.
-+     * If the map is modified while an iteration over the set is in progress
-+     * (except through the iterator's own <tt>remove</tt> operation, or through
-+     * the <tt>setValue</tt> operation on a map entry returned by the iterator)
-+     * the results of the iteration are undefined.  The set supports element
-+     * removal, which removes the corresponding mapping from the map, via the
-+     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
-+     * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not support
-+     * the <tt>add</tt> or <tt>addAll</tt> operations.
-+     *
-+     * @return a set view of the mappings contained in this map.
-+     */
-+    Set<Map.Entry<K, Collection<V>>> entrySet();
-+
-+    /**
-+     * Returns a java.util.Map<K,Collection<V>> for this MultiMap.
-+     *
-+     * @return the underlying java.util.Map for this MultiMap.
-+     */
-+    Map<K,Collection<V>> map();
-+
-+    // Comparison and hashing
-+
-+    /**
-+     * Compares the specified object with this map for equality.  Returns
-+     * <tt>true</tt> if the given object is also a map and the two Maps
-+     * represent the same mappings.  More formally, two maps <tt>t1</tt> and
-+     * <tt>t2</tt> represent the same mappings if
-+     * <tt>t1.entrySet().equals(t2.entrySet())</tt>.  This ensures that the
-+     * <tt>equals</tt> method works properly across different implementations
-+     * of the <tt>Map</tt> interface.
-+     *
-+     * @param o object to be compared for equality with this map.
-+     * @return <tt>true</tt> if the specified object is equal to this map.
-+     */
-+    boolean equals(Object o);
-+
-+    /**
-+     * Returns the hash code value for this map.  The hash code of a map
-+     * is defined to be the sum of the hashCodes of each entry in the map's
-+     * entrySet view.  This ensures that <tt>t1.equals(t2)</tt> implies
-+     * that <tt>t1.hashCode()==t2.hashCode()</tt> for any two maps
-+     * <tt>t1</tt> and <tt>t2</tt>, as required by the general
-+     * contract of Object.hashCode.
-+     *
-+     * @return the hash code value for this map.
-+     * @see Map.Entry#hashCode()
-+     * @see Object#hashCode()
-+     * @see Object#equals(Object)
-+     * @see #equals(Object)
-+     */
-+    int hashCode();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/OrderedBidiMap.java
-@@ -0,0 +1,63 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines a map that allows bidirectional lookup between key and values
-+ * and retains and provides access to an ordering.
-+ * <p/>
-+ * Implementations should allow a value to be looked up from a key and
-+ * a key to be looked up from a value with equal performance.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface OrderedBidiMap <K,V> extends BidiMap<K, V>, OrderedMap<K, V> {
-+
-+    /**
-+     * Gets a view of this map where the keys and values are reversed.
-+     * <p/>
-+     * Changes to one map will be visible in the other and vice versa.
-+     * This enables both directions of the map to be accessed equally.
-+     * <p/>
-+     * Implementations should seek to avoid creating a new object every time this
-+     * method is called. See <code>AbstractMap.values()</code> etc. Calling this
-+     * method on the inverse map should return the original.
-+     * <p/>
-+     * Implementations must return an <code>OrderedBidiMap</code> instance,
-+     * usually by forwarding to <code>inverseOrderedBidiMap()</code>.
-+     *
-+     * @return an inverted bidirectional map
-+     */
-+    public BidiMap<V, K> inverseBidiMap();
-+
-+    /**
-+     * Gets a view of this map where the keys and values are reversed.
-+     * <p/>
-+     * Changes to one map will be visible in the other and vice versa.
-+     * This enables both directions of the map to be accessed equally.
-+     * <p/>
-+     * Implementations should seek to avoid creating a new object every time this
-+     * method is called. See <code>AbstractMap.values()</code> etc. Calling this
-+     * method on the inverse map should return the original.
-+     *
-+     * @return an inverted bidirectional map
-+     */
-+    public OrderedBidiMap<V, K> inverseOrderedBidiMap();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/OrderedIterator.java
-@@ -0,0 +1,48 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * Defines an iterator that operates over a ordered collections15.
-+ * <p/>
-+ * This iterator allows both forward and reverse iteration through the collection.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface OrderedIterator <E> extends Iterator<E> {
-+
-+    /**
-+     * Checks to see if there is a previous entry that can be iterated to.
-+     *
-+     * @return <code>true</code> if the iterator has a previous element
-+     */
-+    boolean hasPrevious();
-+
-+    /**
-+     * Gets the previous element from the collection.
-+     *
-+     * @return the previous key in the iteration
-+     * @throws java.util.NoSuchElementException
-+     *          if the iteration is finished
-+     */
-+    E previous();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/OrderedMap.java
-@@ -0,0 +1,83 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines a map that maintains order and allows both forward and backward
-+ * iteration through that order.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface OrderedMap <K,V> extends IterableMap<K, V> {
-+
-+    /**
-+     * Obtains an <code>OrderedMapIterator</code> over the map.
-+     * <p/>
-+     * A ordered map iterator is an efficient way of iterating over maps
-+     * in both directions.
-+     * <pre>
-+     * BidiMap map = new TreeBidiMap();
-+     * MapIterator it = map.mapIterator();
-+     * while (it.hasNext()) {
-+     *   Object key = it.next();
-+     *   Object value = it.getValue();
-+     *   it.setValue("newValue");
-+     *   Object previousKey = it.previous();
-+     * }
-+     * </pre>
-+     *
-+     * @return a map iterator
-+     */
-+    OrderedMapIterator<K, V> orderedMapIterator();
-+
-+    /**
-+     * Gets the first key currently in this map.
-+     *
-+     * @return the first key currently in this map
-+     * @throws java.util.NoSuchElementException
-+     *          if this map is empty
-+     */
-+    public K firstKey();
-+
-+    /**
-+     * Gets the last key currently in this map.
-+     *
-+     * @return the last key currently in this map
-+     * @throws java.util.NoSuchElementException
-+     *          if this map is empty
-+     */
-+    public K lastKey();
-+
-+    /**
-+     * Gets the next key after the one specified.
-+     *
-+     * @param key the key to search for next from
-+     * @return the next key, null if no match or at end
-+     */
-+    public K nextKey(K key);
-+
-+    /**
-+     * Gets the previous key before the one specified.
-+     *
-+     * @param key the key to search for previous from
-+     * @return the previous key, null if no match or at start
-+     */
-+    public K previousKey(K key);
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/OrderedMapIterator.java
-@@ -0,0 +1,46 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines an iterator that operates over an ordered <code>Map</code>.
-+ * <p/>
-+ * This iterator allows both forward and reverse iteration through the map.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface OrderedMapIterator <K,V> extends MapIterator<K, V>, OrderedIterator<K> {
-+
-+    /**
-+     * Checks to see if there is a previous entry that can be iterated to.
-+     *
-+     * @return <code>true</code> if the iterator has a previous element
-+     */
-+    boolean hasPrevious();
-+
-+    /**
-+     * Gets the previous <em>key</em> from the <code>Map</code>.
-+     *
-+     * @return the previous key in the iteration
-+     * @throws java.util.NoSuchElementException
-+     *          if the iteration is finished
-+     */
-+    K previous();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/Predicate.java
-@@ -0,0 +1,49 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines a functor interface implemented by classes that perform a predicate
-+ * test on an object.
-+ * <p/>
-+ * A <code>Predicate</code> is the object equivalent of an <code>if</code> statement.
-+ * It uses the input object to return a true or false value, and is often used in
-+ * validation or filtering.
-+ * <p/>
-+ * Standard implementations of common predicates are provided by
-+ * {@link PredicateUtils}. These include true, false, instanceof, equals, and,
-+ * or, not, method invokation and null testing.
-+ *
-+ * @author James Strachan
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public interface Predicate <T> {
-+
-+    /**
-+     * Use the specified parameter to perform a test that returns true or false.
-+     *
-+     * @param object the object to evaluate, should not be changed
-+     * @return true or false
-+     * @throws ClassCastException       (runtime) if the input is the wrong class
-+     * @throws IllegalArgumentException (runtime) if the input is invalid
-+     * @throws FunctorException         (runtime) if the predicate encounters a problem
-+     */
-+    public boolean evaluate(T object);
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/PredicateUtils.java
-@@ -0,0 +1,488 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.functors.*;
-+
-+import java.util.Collection;
-+
-+/**
-+ * <code>PredicateUtils</code> provides reference implementations and utilities
-+ * for the Predicate functor interface. The supplied predicates are:
-+ * <ul>
-+ * <li>Invoker - returns the result of a method call on the input object
-+ * <li>InstanceOf - true if the object is an instanceof a class
-+ * <li>Equal - true if the object equals() a specified object
-+ * <li>Identity - true if the object == a specified object
-+ * <li>Null - true if the object is null
-+ * <li>NotNull - true if the object is not null
-+ * <li>Unique - true if the object has not already been evaluated
-+ * <li>And/All - true if all of the predicates are true
-+ * <li>Or/Any - true if any of the predicates is true
-+ * <li>Either/One - true if only one of the predicate is true
-+ * <li>Neither/None - true if none of the predicates are true
-+ * <li>Not - true if the predicate is false, and vice versa
-+ * <li>Transformer - wraps a Transformer as a Predicate
-+ * <li>True - always return true
-+ * <li>False - always return false
-+ * <li>Exception - always throws an exception
-+ * <li>NullIsException/NullIsFalse/NullIsTrue - check for null input
-+ * <li>Transformed - transforms the input before calling the predicate
-+ * </ul>
-+ * All the supplied predicates are Serializable.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Ola Berg
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicateUtils {
-+
-+    /**
-+     * This class is not normally instantiated.
-+     */
-+    public PredicateUtils() {
-+        super();
-+    }
-+
-+    // Simple predicates
-+    //-----------------------------------------------------------------------------
-+
-+    /**
-+     * Gets a Predicate that always throws an exception.
-+     * This could be useful during testing as a placeholder.
-+     *
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.ExceptionPredicate
-+     */
-+    public static Predicate exceptionPredicate() {
-+        return ExceptionPredicate.INSTANCE;
-+    }
-+
-+    /**
-+     * Gets a Predicate that always returns true.
-+     *
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.TruePredicate
-+     */
-+    public static <T> Predicate<T> truePredicate() {
-+        return TruePredicate.getInstance();
-+    }
-+
-+    /**
-+     * Gets a Predicate that always returns false.
-+     *
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.FalsePredicate
-+     */
-+    public static <T> Predicate<T> falsePredicate() {
-+        return FalsePredicate.getInstance();
-+    }
-+
-+    /**
-+     * Gets a Predicate that checks if the input object passed in is null.
-+     *
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.NullPredicate
-+     */
-+    public static <T> Predicate<T> nullPredicate() {
-+        return NullPredicate.getInstance();
-+    }
-+
-+    /**
-+     * Gets a Predicate that checks if the input object passed in is not null.
-+     *
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.NotNullPredicate
-+     */
-+    public static <T> Predicate<T> notNullPredicate() {
-+        return NotNullPredicate.getInstance();
-+    }
-+
-+    /**
-+     * Creates a Predicate that checks if the input object is equal to the
-+     * specified object using equals().
-+     *
-+     * @param value the value to compare against
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.EqualPredicate
-+     */
-+    public static <T> Predicate<T> equalPredicate(T value) {
-+        return EqualPredicate.getInstance(value);
-+    }
-+
-+    /**
-+     * Creates a Predicate that checks if the input object is equal to the
-+     * specified object by identity.
-+     *
-+     * @param value the value to compare against
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.IdentityPredicate
-+     */
-+    public static <T> Predicate<T> identityPredicate(T value) {
-+        return IdentityPredicate.getInstance(value);
-+    }
-+
-+    /**
-+     * Creates a Predicate that checks if the object passed in is of
-+     * a particular type, using instanceof. A <code>null</code> input
-+     * object will return <code>false</code>.
-+     *
-+     * @param type the type to check for, may not be null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the class is null
-+     * @see org.apache.commons.collections15.functors.InstanceofPredicate
-+     */
-+    @SuppressWarnings("unchecked")
-+    public static Predicate instanceofPredicate(Class type) {
-+        return InstanceofPredicate.getInstance(type);
-+    }
-+
-+    /**
-+     * Creates a Predicate that returns true the first time an object is
-+     * encountered, and false if the same object is received
-+     * again. The comparison is by equals(). A <code>null</code> input object
-+     * is accepted and will return true the first time, and false subsequently
-+     * as well.
-+     *
-+     * @return the predicate
-+     * @see org.apache.commons.collections15.functors.UniquePredicate
-+     */
-+    public static <T> Predicate<T> uniquePredicate() {
-+        // must return new instance each time
-+        return UniquePredicate.getInstance();
-+    }
-+
-+    /**
-+     * Creates a Predicate that invokes a method on the input object.
-+     * The method must return either a boolean or a non-null Boolean,
-+     * and have no parameters. If the input object is null, a
-+     * PredicateException is thrown.
-+     * <p/>
-+     * For example, <code>PredicateUtils.invokerPredicate("isEmpty");</code>
-+     * will call the <code>isEmpty</code> method on the input object to
-+     * determine the predicate result.
-+     *
-+     * @param methodName the method name to call on the input object, may not be null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the methodName is null.
-+     * @see org.apache.commons.collections15.functors.InvokerTransformer
-+     * @see org.apache.commons.collections15.functors.TransformerPredicate
-+     */
-+    public static Predicate invokerPredicate(String methodName) {
-+        // reuse transformer as it has caching - this is lazy really, should have inner class here
-+        return asPredicate(InvokerTransformer.getInstance(methodName));
-+    }
-+
-+    /**
-+     * Creates a Predicate that invokes a method on the input object.
-+     * The method must return either a boolean or a non-null Boolean,
-+     * and have no parameters. If the input object is null, a
-+     * PredicateException is thrown.
-+     * <p/>
-+     * For example, <code>PredicateUtils.invokerPredicate("isEmpty");</code>
-+     * will call the <code>isEmpty</code> method on the input object to
-+     * determine the predicate result.
-+     *
-+     * @param methodName the method name to call on the input object, may not be null
-+     * @param paramTypes the parameter types
-+     * @param args       the arguments
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the method name is null
-+     * @throws IllegalArgumentException if the paramTypes and args don't match
-+     * @see org.apache.commons.collections15.functors.InvokerTransformer
-+     * @see org.apache.commons.collections15.functors.TransformerPredicate
-+     */
-+    public static Predicate invokerPredicate(String methodName, Class[] paramTypes, Object[] args) {
-+        // reuse transformer as it has caching - this is lazy really, should have inner class here
-+        return asPredicate(InvokerTransformer.getInstance(methodName, paramTypes, args));
-+    }
-+
-+    // Boolean combinations
-+    //-----------------------------------------------------------------------------
-+
-+    /**
-+     * Create a new Predicate that returns true only if both of the specified
-+     * predicates are true.
-+     *
-+     * @param predicate1 the first predicate, may not be null
-+     * @param predicate2 the second predicate, may not be null
-+     * @return the <code>and</code> predicate
-+     * @throws IllegalArgumentException if either predicate is null
-+     * @see org.apache.commons.collections15.functors.AndPredicate
-+     */
-+    public static <T> Predicate<T> andPredicate(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        return AndPredicate.<T>getInstance(predicate1, predicate2);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true only if all of the specified
-+     * predicates are true.
-+     *
-+     * @param predicates an array of predicates to check, may not be null
-+     * @return the <code>all</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @see org.apache.commons.collections15.functors.AllPredicate
-+     */
-+    public static <T> Predicate<T> allPredicate(Predicate<? super T> ... predicates) {
-+        return AllPredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true only if all of the specified
-+     * predicates are true. The predicates are checked in iterator order.
-+     *
-+     * @param predicates a collection of predicates to check, may not be null
-+     * @return the <code>all</code> predicate
-+     * @throws IllegalArgumentException if the predicates collection is null
-+     * @throws IllegalArgumentException if the predicates collection has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the collection is null
-+     * @see org.apache.commons.collections15.functors.AllPredicate
-+     */
-+    public static <T> Predicate<T> allPredicate(Collection<Predicate<? super T>> predicates) {
-+        return AllPredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if either of the specified
-+     * predicates are true.
-+     *
-+     * @param predicate1 the first predicate, may not be null
-+     * @param predicate2 the second predicate, may not be null
-+     * @return the <code>or</code> predicate
-+     * @throws IllegalArgumentException if either predicate is null
-+     * @see org.apache.commons.collections15.functors.OrPredicate
-+     */
-+    public static <T> Predicate<T> orPredicate(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        return OrPredicate.<T>getInstance(predicate1, predicate2);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if any of the specified
-+     * predicates are true.
-+     *
-+     * @param predicates an array of predicates to check, may not be null
-+     * @return the <code>any</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @see org.apache.commons.collections15.functors.AnyPredicate
-+     */
-+    public static <T> Predicate<T> anyPredicate(Predicate<? super T> ... predicates) {
-+        return AnyPredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if any of the specified
-+     * predicates are true. The predicates are checked in iterator order.
-+     *
-+     * @param predicates a collection of predicates to check, may not be null
-+     * @return the <code>any</code> predicate
-+     * @throws IllegalArgumentException if the predicates collection is null
-+     * @throws IllegalArgumentException if the predicates collection has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the collection is null
-+     * @see org.apache.commons.collections15.functors.AnyPredicate
-+     */
-+    public static <T> Predicate<T> anyPredicate(Collection<Predicate<? super T>> predicates) {
-+        return AnyPredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if one, but not both, of the
-+     * specified predicates are true.
-+     *
-+     * @param predicate1 the first predicate, may not be null
-+     * @param predicate2 the second predicate, may not be null
-+     * @return the <code>either</code> predicate
-+     * @throws IllegalArgumentException if either predicate is null
-+     * @see org.apache.commons.collections15.functors.OnePredicate
-+     */
-+    @SuppressWarnings("unchecked")
-+    public static <T> Predicate<T> eitherPredicate(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        return onePredicate(new Predicate[]{predicate1, predicate2});
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if only one of the specified
-+     * predicates are true.
-+     *
-+     * @param predicates an array of predicates to check, may not be null
-+     * @return the <code>one</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @see org.apache.commons.collections15.functors.OnePredicate
-+     */
-+    public static <T> Predicate<T> onePredicate(Predicate<? super T> ... predicates) {
-+        return OnePredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if only one of the specified
-+     * predicates are true. The predicates are checked in iterator order.
-+     *
-+     * @param predicates a collection of predicates to check, may not be null
-+     * @return the <code>one</code> predicate
-+     * @throws IllegalArgumentException if the predicates collection is null
-+     * @throws IllegalArgumentException if the predicates collection has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the collection is null
-+     * @see org.apache.commons.collections15.functors.OnePredicate
-+     */
-+    public static <T> Predicate<T> onePredicate(Collection<Predicate<? super T>> predicates) {
-+        return OnePredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if neither of the specified
-+     * predicates are true.
-+     *
-+     * @param predicate1 the first predicate, may not be null
-+     * @param predicate2 the second predicate, may not be null
-+     * @return the <code>neither</code> predicate
-+     * @throws IllegalArgumentException if either predicate is null
-+     * @see org.apache.commons.collections15.functors.NonePredicate
-+     */
-+    @SuppressWarnings("unchecked")
-+    public static <T> Predicate<T> neitherPredicate(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        return nonePredicate(new Predicate[]{predicate1, predicate2});
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if none of the specified
-+     * predicates are true.
-+     *
-+     * @param predicates an array of predicates to check, may not be null
-+     * @return the <code>none</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @see org.apache.commons.collections15.functors.NonePredicate
-+     */
-+    public static <T> Predicate<T> nonePredicate(Predicate<? super T> ... predicates) {
-+        return NonePredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if none of the specified
-+     * predicates are true. The predicates are checked in iterator order.
-+     *
-+     * @param predicates a collection of predicates to check, may not be null
-+     * @return the <code>none</code> predicate
-+     * @throws IllegalArgumentException if the predicates collection is null
-+     * @throws IllegalArgumentException if the predicates collection has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the collection is null
-+     * @see org.apache.commons.collections15.functors.NonePredicate
-+     */
-+    public static <T> Predicate<T> nonePredicate(Collection<Predicate<? super T>> predicates) {
-+        return NonePredicate.getInstance(predicates);
-+    }
-+
-+    /**
-+     * Create a new Predicate that returns true if the specified predicate
-+     * returns false and vice versa.
-+     *
-+     * @param predicate the predicate to not
-+     * @return the <code>not</code> predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     * @see org.apache.commons.collections15.functors.NotPredicate
-+     */
-+    public static <T> Predicate<T> notPredicate(Predicate<T> predicate) {
-+        return NotPredicate.getInstance(predicate);
-+    }
-+
-+    // Adaptors
-+    //-----------------------------------------------------------------------------
-+
-+    /**
-+     * Create a new Predicate that wraps a Transformer. The Transformer must
-+     * return either Boolean.TRUE or Boolean.FALSE otherwise a PredicateException
-+     * will be thrown.
-+     *
-+     * @param transformer the transformer to wrap, may not be null
-+     * @return the transformer wrapping predicate
-+     * @throws IllegalArgumentException if the transformer is null
-+     * @see org.apache.commons.collections15.functors.TransformerPredicate
-+     */
-+    public static <T> Predicate<T> asPredicate(Transformer<T, Boolean> transformer) {
-+        return TransformerPredicate.getInstance(transformer);
-+    }
-+
-+    // Null handlers
-+    //-----------------------------------------------------------------------------
-+
-+    /**
-+     * Gets a Predicate that throws an exception if the input object is null,
-+     * otherwise it calls the specified Predicate. This allows null handling
-+     * behaviour to be added to Predicates that don't support nulls.
-+     *
-+     * @param predicate the predicate to wrap, may not be null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null.
-+     * @see org.apache.commons.collections15.functors.NullIsExceptionPredicate
-+     */
-+    public static <T> Predicate<T> nullIsExceptionPredicate(Predicate<T> predicate) {
-+        return NullIsExceptionPredicate.getInstance(predicate);
-+    }
-+
-+    /**
-+     * Gets a Predicate that returns false if the input object is null, otherwise
-+     * it calls the specified Predicate. This allows null handling behaviour to
-+     * be added to Predicates that don't support nulls.
-+     *
-+     * @param predicate the predicate to wrap, may not be null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null.
-+     * @see org.apache.commons.collections15.functors.NullIsFalsePredicate
-+     */
-+    public static <T> Predicate<T> nullIsFalsePredicate(Predicate<T> predicate) {
-+        return NullIsFalsePredicate.getInstance(predicate);
-+    }
-+
-+    /**
-+     * Gets a Predicate that returns true if the input object is null, otherwise
-+     * it calls the specified Predicate. This allows null handling behaviour to
-+     * be added to Predicates that don't support nulls.
-+     *
-+     * @param predicate the predicate to wrap, may not be null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null.
-+     * @see org.apache.commons.collections15.functors.NullIsTruePredicate
-+     */
-+    public static <T> Predicate<T> nullIsTruePredicate(Predicate<T> predicate) {
-+        return NullIsTruePredicate.getInstance(predicate);
-+    }
-+
-+    // Transformed
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Creates a predicate that transforms the input object before passing it
-+     * to the predicate.
-+     *
-+     * @param transformer the transformer to call first
-+     * @param predicate   the predicate to call with the result of the transform
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the transformer or the predicate is null
-+     * @see org.apache.commons.collections15.functors.TransformedPredicate
-+     * @since Commons Collections 3.1
-+     */
-+    public static <I,O> Predicate<I> transformedPredicate(Transformer<I, ? extends O> transformer, Predicate<? super O> predicate) {
-+        return TransformedPredicate.getInstance(transformer, predicate);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/ResettableIterator.java
-@@ -0,0 +1,38 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * Defines an iterator that can be reset back to an initial state.
-+ * <p/>
-+ * This interface allows an iterator to be repeatedly reused.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface ResettableIterator <E> extends Iterator<E> {
-+
-+    /**
-+     * Resets the iterator back to the position at which the iterator
-+     * was created.
-+     */
-+    public void reset();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/ResettableListIterator.java
-@@ -0,0 +1,38 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.ListIterator;
-+
-+/**
-+ * Defines a list iterator that can be reset back to an initial state.
-+ * <p/>
-+ * This interface allows an iterator to be repeatedly reused.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface ResettableListIterator <E> extends ListIterator<E>, ResettableIterator<E> {
-+
-+    /**
-+     * Resets the iterator back to the position at which the iterator
-+     * was created.
-+     */
-+    public void reset();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/SetUtils.java
-@@ -0,0 +1,312 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.set.*;
-+
-+import java.util.*;
-+
-+/**
-+ * Provides utility methods and decorators for
-+ * {@link Set} and {@link SortedSet} instances.
-+ *
-+ * @author Paul Jack
-+ * @author Stephen Colebourne
-+ * @author Neil O'Toole
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.1
-+ */
-+public class SetUtils {
-+
-+    /**
-+     * An empty unmodifiable set.
-+     * This uses the {@link Collections} implementation
-+     * and is provided for completeness.
-+     */
-+    public static final Set EMPTY_SET = Collections.EMPTY_SET;
-+    /**
-+     * An empty unmodifiable sorted set.
-+     * This is not provided in the JDK.
-+     */
-+    public static final SortedSet EMPTY_SORTED_SET = UnmodifiableSortedSet.decorate(new TreeSet());
-+
-+    /**
-+     * <code>SetUtils</code> should not normally be instantiated.
-+     */
-+    public SetUtils() {
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Tests two sets for equality as per the <code>equals()</code> contract
-+     * in {@link java.util.Set#equals(java.lang.Object)}.
-+     * <p/>
-+     * This method is useful for implementing <code>Set</code> when you cannot
-+     * extend AbstractSet. The method takes Collection instances to enable other
-+     * collection types to use the Set implementation algorithm.
-+     * <p/>
-+     * The relevant text (slightly paraphrased as this is a static method) is:
-+     * <blockquote>
-+     * <p>Two sets are considered equal if they have
-+     * the same size, and every member of the first set is contained in
-+     * the second. This ensures that the <tt>equals</tt> method works
-+     * properly across different implementations of the <tt>Set</tt>
-+     * interface.</p>
-+     * <p/>
-+     * <p/>
-+     * This implementation first checks if the two sets are the same object:
-+     * if so it returns <tt>true</tt>.  Then, it checks if the two sets are
-+     * identical in size; if not, it returns false. If so, it returns
-+     * <tt>a.containsAll((Collection) b)</tt>.</p>
-+     * </blockquote>
-+     *
-+     * @param set1 the first set, may be null
-+     * @param set2 the second set, may be null
-+     * @return whether the sets are equal by value comparison
-+     * @see java.util.Set
-+     */
-+    public static boolean isEqualSet(final Collection set1, final Collection set2) {
-+        if (set1 == set2) {
-+            return true;
-+        }
-+        if (set1 == null || set2 == null || set1.size() != set2.size()) {
-+            return false;
-+        }
-+
-+        return set1.containsAll(set2);
-+    }
-+
-+    /**
-+     * Generates a hash code using the algorithm specified in
-+     * {@link java.util.Set#hashCode()}.
-+     * <p/>
-+     * This method is useful for implementing <code>Set</code> when you cannot
-+     * extend AbstractSet. The method takes Collection instances to enable other
-+     * collection types to use the Set implementation algorithm.
-+     *
-+     * @param set the set to calculate the hash code for, may be null
-+     * @return the hash code
-+     * @see java.util.Set#hashCode()
-+     */
-+    public static int hashCodeForSet(final Collection set) {
-+        if (set == null) {
-+            return 0;
-+        }
-+        int hashCode = 0;
-+        Iterator it = set.iterator();
-+        Object obj = null;
-+
-+        while (it.hasNext()) {
-+            obj = it.next();
-+            if (obj != null) {
-+                hashCode += obj.hashCode();
-+            }
-+        }
-+        return hashCode;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized set backed by the given set.
-+     * <p/>
-+     * You must manually synchronize on the returned buffer's iterator to
-+     * avoid non-deterministic behavior:
-+     * <p/>
-+     * <pre>
-+     * Set s = SetUtils.synchronizedSet(mySet);
-+     * synchronized (s) {
-+     *     Iterator i = s.iterator();
-+     *     while (i.hasNext()) {
-+     *         process (i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param set the set to synchronize, must not be null
-+     * @return a synchronized set backed by the given set
-+     * @throws IllegalArgumentException if the set is null
-+     */
-+    public static <E> Set<E> synchronizedSet(Set<E> set) {
-+        return SynchronizedSet.decorate(set);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable set backed by the given set.
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param set the set to make unmodifiable, must not be null
-+     * @return an unmodifiable set backed by the given set
-+     * @throws IllegalArgumentException if the set is null
-+     */
-+    public static <E> Set<E> unmodifiableSet(Set<E> set) {
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) set backed by the given set.
-+     * <p/>
-+     * Only objects that pass the test in the given predicate can be added to the set.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * It is important not to use the original set after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param set       the set to predicate, must not be null
-+     * @param predicate the predicate for the set, must not be null
-+     * @return a predicated set backed by the given set
-+     * @throws IllegalArgumentException if the Set or Predicate is null
-+     */
-+    public static <E> Set<E> predicatedSet(Set<E> set, Predicate<? super E> predicate) {
-+        return PredicatedSet.decorate(set, predicate);
-+    }
-+
-+    /**
-+     * Returns a typed set backed by the given set.
-+     * <p/>
-+     * Only objects of the specified type can be added to the set.
-+     *
-+     * @param set  the set to limit to a specific type, must not be null
-+     * @param type the type of objects which may be added to the set
-+     * @return a typed set backed by the specified set
-+     * @deprecated Made obsolete by Java 1.5 generics.
-+     */
-+    public static <E> Set<E> typedSet(Set<E> set, Class<E> type) {
-+        return TypedSet.decorate(set, type);
-+    }
-+
-+    /**
-+     * Returns a transformed set backed by the given set.
-+     * <p/>
-+     * Each object is passed through the transformer as it is added to the
-+     * Set. It is important not to use the original set after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param set         the set to transform, must not be null
-+     * @param transformer the transformer for the set, must not be null
-+     * @return a transformed set backed by the given set
-+     * @throws IllegalArgumentException if the Set or Transformer is null
-+     */
-+    public static <I,O> Set<O> transformedSet(Set<I> set, Transformer<? super I, ? extends O> transformer) {
-+        return TransformedSet.decorate(set, transformer);
-+    }
-+
-+    /**
-+     * Returns a set that maintains the order of elements that are added
-+     * backed by the given set.
-+     * <p/>
-+     * If an element is added twice, the order is determined by the first add.
-+     * The order is observed through the iterator or toArray.
-+     *
-+     * @param set the set to order, must not be null
-+     * @return an ordered set backed by the given set
-+     * @throws IllegalArgumentException if the Set is null
-+     */
-+    public static <E> Set<E> orderedSet(Set<E> set) {
-+        return ListOrderedSet.decorate(set);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a synchronized sorted set backed by the given sorted set.
-+     * <p/>
-+     * You must manually synchronize on the returned buffer's iterator to
-+     * avoid non-deterministic behavior:
-+     * <p/>
-+     * <pre>
-+     * Set s = SetUtils.synchronizedSet(mySet);
-+     * synchronized (s) {
-+     *     Iterator i = s.iterator();
-+     *     while (i.hasNext()) {
-+     *         process (i.next());
-+     *     }
-+     * }
-+     * </pre>
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param set the sorted set to synchronize, must not be null
-+     * @return a synchronized set backed by the given set
-+     * @throws IllegalArgumentException if the set is null
-+     */
-+    public static <E> SortedSet<E> synchronizedSortedSet(SortedSet<E> set) {
-+        return SynchronizedSortedSet.decorate(set);
-+    }
-+
-+    /**
-+     * Returns an unmodifiable sorted set backed by the given sorted set.
-+     * <p/>
-+     * This method uses the implementation in the decorators subpackage.
-+     *
-+     * @param set the sorted set to make unmodifiable, must not be null
-+     * @return an unmodifiable set backed by the given set
-+     * @throws IllegalArgumentException if the set is null
-+     */
-+    public static <E> SortedSet<E> unmodifiableSortedSet(SortedSet<E> set) {
-+        return UnmodifiableSortedSet.decorate(set);
-+    }
-+
-+    /**
-+     * Returns a predicated (validating) sorted set backed by the given sorted set.
-+     * <p/>
-+     * Only objects that pass the test in the given predicate can be added to the set.
-+     * Trying to add an invalid object results in an IllegalArgumentException.
-+     * It is important not to use the original set after invoking this method,
-+     * as it is a backdoor for adding invalid objects.
-+     *
-+     * @param set       the sorted set to predicate, must not be null
-+     * @param predicate the predicate for the sorted set, must not be null
-+     * @return a predicated sorted set backed by the given sorted set
-+     * @throws IllegalArgumentException if the Set or Predicate is null
-+     */
-+    public static <E> SortedSet<E> predicatedSortedSet(SortedSet<E> set, Predicate<? super E> predicate) {
-+        return PredicatedSortedSet.decorate(set, predicate);
-+    }
-+
-+    /**
-+     * Returns a typed sorted set backed by the given set.
-+     * <p/>
-+     * Only objects of the specified type can be added to the set.
-+     *
-+     * @param set  the set to limit to a specific type, must not be null
-+     * @param type the type of objects which may be added to the set
-+     * @return a typed set backed by the specified set
-+     * @deprecated made obsolete by Java 1.5 generics.
-+     */
-+    public static <E> SortedSet<E> typedSortedSet(SortedSet<E> set, Class<E> type) {
-+        return TypedSortedSet.decorate(set, type);
-+    }
-+
-+    /**
-+     * Returns a transformed sorted set backed by the given set.
-+     * <p/>
-+     * Each object is passed through the transformer as it is added to the
-+     * Set. It is important not to use the original set after invoking this
-+     * method, as it is a backdoor for adding untransformed objects.
-+     *
-+     * @param set         the set to transform, must not be null
-+     * @param transformer the transformer for the set, must not be null
-+     * @return a transformed set backed by the given set
-+     * @throws IllegalArgumentException if the Set or Transformer is null
-+     */
-+    public static <I,O> SortedSet<O> transformedSortedSet(SortedSet<I> set, Transformer<? super I, ? extends O> transformer) {
-+        return TransformedSortedSet.decorate(set, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/SortedBag.java
-@@ -0,0 +1,53 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.Comparator;
-+
-+/**
-+ * Defines a type of <code>Bag</code> that maintains a sorted order among
-+ * its unique representative members.
-+ *
-+ * @author Matt Hall, John Watkinson, Chuck Burdick
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 2.0
-+ */
-+public interface SortedBag <E> extends Bag<E> {
-+
-+    /**
-+     * Returns the comparator associated with this sorted set, or null
-+     * if it uses its elements' natural ordering.
-+     *
-+     * @return the comparator in use, or null if natural ordering
-+     */
-+    public Comparator<? super E> comparator();
-+
-+    /**
-+     * Returns the first (lowest) member.
-+     *
-+     * @return the first element in the sorted bag
-+     */
-+    public E first();
-+
-+    /**
-+     * Returns the last (highest) member.
-+     *
-+     * @return the last element in the sorted bag
-+     */
-+    public E last();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/SortedBidiMap.java
-@@ -0,0 +1,68 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import java.util.SortedMap;
-+
-+/**
-+ * Defines a map that allows bidirectional lookup between key and values
-+ * and retains both keys and values in sorted order.
-+ * <p/>
-+ * Implementations should allow a value to be looked up from a key and
-+ * a key to be looked up from a value with equal performance.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface SortedBidiMap <K,V> extends OrderedBidiMap<K, V>, SortedMap<K, V> {
-+
-+    /**
-+     * Gets a view of this map where the keys and values are reversed.
-+     * <p/>
-+     * Changes to one map will be visible in the other and vice versa.
-+     * This enables both directions of the map to be accessed equally.
-+     * <p/>
-+     * Implementations should seek to avoid creating a new object every time this
-+     * method is called. See <code>AbstractMap.values()</code> etc. Calling this
-+     * method on the inverse map should return the original.
-+     * <p/>
-+     * Implementations must return a <code>SortedBidiMap</code> instance,
-+     * usually by forwarding to <code>inverseSortedBidiMap()</code>.
-+     *
-+     * @return an inverted bidirectional map
-+     */
-+    public BidiMap<V, K> inverseBidiMap();
-+
-+    /**
-+     * Gets a view of this map where the keys and values are reversed.
-+     * <p/>
-+     * Changes to one map will be visible in the other and vice versa.
-+     * This enables both directions of the map to be accessed as a <code>SortedMap</code>.
-+     * <p/>
-+     * Implementations should seek to avoid creating a new object every time this
-+     * method is called. See <code>AbstractMap.values()</code> etc. Calling this
-+     * method on the inverse map should return the original.
-+     * <p/>
-+     * The inverse map returned by <code>inverseBidiMap()</code> should be the
-+     * same object as returned by this method.
-+     *
-+     * @return an inverted bidirectional map
-+     */
-+    public SortedBidiMap<V, K> inverseSortedBidiMap();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/Transformer.java
-@@ -0,0 +1,50 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Defines a functor interface implemented by classes that transform one
-+ * object into another.
-+ * <p/>
-+ * A <code>Transformer</code> converts the input object to the output object.
-+ * The input object should be left unchanged.
-+ * Transformers are typically used for type conversions, or extracting data
-+ * from an object.
-+ * <p/>
-+ * Standard implementations of common transformers are provided by
-+ * {@link TransformerUtils}. These include method invokation, returning a constant,
-+ * cloning and returning the string value.
-+ *
-+ * @author James Strachan
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 1.0
-+ */
-+public interface Transformer <I,O> {
-+
-+    /**
-+     * Transforms the input object (leaving it unchanged) into some output object.
-+     *
-+     * @param input the object to be transformed, should be left unchanged
-+     * @return a transformed object
-+     * @throws ClassCastException       (runtime) if the input is the wrong class
-+     * @throws IllegalArgumentException (runtime) if the input is invalid
-+     * @throws FunctorException         (runtime) if the transform cannot be completed
-+     */
-+    public O transform(I input);
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/TransformerUtils.java
-@@ -0,0 +1,414 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+import org.apache.commons.collections15.functors.*;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Map;
-+
-+/**
-+ * <code>TransformerUtils</code> provides reference implementations and
-+ * utilities for the Transformer functor interface. The supplied transformers are:
-+ * <ul>
-+ * <li>Invoker - returns the result of a method call on the input object
-+ * <li>Clone - returns a clone of the input object
-+ * <li>Constant - always returns the same object
-+ * <li>Closure - performs a Closure and returns the input object
-+ * <li>Predicate - returns the result of the predicate as a Boolean
-+ * <li>Factory - returns a new object from a factory
-+ * <li>Chained - chains two or more transformers together
-+ * <li>Switch - calls one transformer based on one or more predicates
-+ * <li>SwitchMap - calls one transformer looked up from a Map
-+ * <li>Instantiate - the Class input object is instantiated
-+ * <li>Map - returns an object from a supplied Map
-+ * <li>Null - always returns null
-+ * <li>NOP - returns the input object, which should be immutable
-+ * <li>Exception - always throws an exception
-+ * <li>StringValue - returns a <code>java.lang.String</code> representation of the input object
-+ * </ul>
-+ * All the supplied transformers are Serializable.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, James Carman
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformerUtils {
-+
-+    /**
-+     * This class is not normally instantiated.
-+     */
-+    public TransformerUtils() {
-+        super();
-+    }
-+
-+    /**
-+     * Gets a transformer that always throws an exception.
-+     * This could be useful during testing as a placeholder.
-+     *
-+     * @return the transformer
-+     * @see org.apache.commons.collections15.functors.ExceptionTransformer
-+     */
-+    public static Transformer exceptionTransformer() {
-+        return ExceptionTransformer.INSTANCE;
-+    }
-+
-+    /**
-+     * Gets a transformer that always returns null.
-+     *
-+     * @return the transformer
-+     * @see org.apache.commons.collections15.functors.ConstantTransformer
-+     */
-+    public static Transformer nullTransformer() {
-+        return ConstantTransformer.NULL_INSTANCE;
-+    }
-+
-+    /**
-+     * Gets a transformer that returns the input object.
-+     * The input object should be immutable to maintain the
-+     * contract of Transformer (although this is not checked).
-+     *
-+     * @return the transformer
-+     * @see org.apache.commons.collections15.functors.NOPTransformer
-+     */
-+    public static Transformer nopTransformer() {
-+        return NOPTransformer.INSTANCE;
-+    }
-+
-+    /**
-+     * Gets a transformer that returns a clone of the input
-+     * object. The input object will be cloned using one of these
-+     * techniques (in order):
-+     * <ul>
-+     * <li>public clone method
-+     * <li>public copy constructor
-+     * <li>serialization clone
-+     * <ul>
-+     *
-+     * @return the transformer
-+     * @see org.apache.commons.collections15.functors.CloneTransformer
-+     */
-+    public static Transformer cloneTransformer() {
-+        return CloneTransformer.INSTANCE;
-+    }
-+
-+    /**
-+     * Creates a Transformer that will return the same object each time the
-+     * transformer is used.
-+     *
-+     * @param constantToReturn the constant object to return each time in the transformer
-+     * @return the transformer.
-+     * @see org.apache.commons.collections15.functors.ConstantTransformer
-+     */
-+    public static <T> Transformer<Object, T> constantTransformer(T constantToReturn) {
-+        return ConstantTransformer.getInstance(constantToReturn);
-+    }
-+
-+    /**
-+     * Creates a Transformer that calls a Closure each time the transformer is used.
-+     * The transformer returns the input object.
-+     *
-+     * @param closure the closure to run each time in the transformer, not null
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the closure is null
-+     * @see org.apache.commons.collections15.functors.ClosureTransformer
-+     */
-+    public static <T> Transformer<T, T> asTransformer(Closure<T> closure) {
-+        return ClosureTransformer.getInstance(closure);
-+    }
-+
-+    /**
-+     * Creates a Transformer that calls a Predicate each time the transformer is used.
-+     * The transformer will return either Boolean.TRUE or Boolean.FALSE.
-+     *
-+     * @param predicate the predicate to run each time in the transformer, not null
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the predicate is null
-+     * @see org.apache.commons.collections15.functors.PredicateTransformer
-+     */
-+    public static <T> Transformer<T, Boolean> asTransformer(Predicate<T> predicate) {
-+        return PredicateTransformer.getInstance(predicate);
-+    }
-+
-+    /**
-+     * Creates a Transformer that calls a Factory each time the transformer is used.
-+     * The transformer will return the value returned by the factory.
-+     *
-+     * @param factory the factory to run each time in the transformer, not null
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the factory is null
-+     * @see org.apache.commons.collections15.functors.FactoryTransformer
-+     */
-+    public static <T> Transformer<Object, T> asTransformer(Factory<T> factory) {
-+        return FactoryTransformer.getInstance(factory);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls two transformers, passing the result of
-+     * the first into the second.
-+     *
-+     * @param transformer1 the first transformer
-+     * @param transformer2 the second transformer
-+     * @return the transformer
-+     * @throws IllegalArgumentException if either transformer is null
-+     * @see org.apache.commons.collections15.functors.ChainedTransformer
-+     */
-+    public static <I,M,O> Transformer<I, O> chainedTransformer(Transformer<I, ? extends M> transformer1, Transformer<? super M, O> transformer2) {
-+        return ChainedTransformer.getInstance(transformer1, transformer2);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls each transformer in turn, passing the
-+     * result into the next transformer.
-+     * <p/>
-+     * Note-- no type safety provided by generics.
-+     *
-+     * @param transformers an array of transformers to chain
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the transformers array is null
-+     * @throws IllegalArgumentException if any transformer in the array is null
-+     * @see org.apache.commons.collections15.functors.ChainedTransformer
-+     */
-+    public static <I,O> Transformer<I, O> chainedTransformer(Transformer[] transformers) {
-+        return ChainedTransformer.getInstance(transformers);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls each transformer in turn, passing the
-+     * result into the next transformer. The ordering is that of the iterator()
-+     * method on the collection.
-+     * <p/>
-+     * Note-- no type safety provided by generics.
-+     *
-+     * @param transformers a collection of transformers to chain
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the transformers collection is null
-+     * @throws IllegalArgumentException if any transformer in the collection is null
-+     * @see org.apache.commons.collections15.functors.ChainedTransformer
-+     */
-+    public static <I,O> Transformer<I, O> chainedTransformer(Collection transformers) {
-+        return ChainedTransformer.getInstance(transformers);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls one of two transformers depending
-+     * on the specified predicate.
-+     *
-+     * @param predicate        the predicate to switch on
-+     * @param trueTransformer  the transformer called if the predicate is true
-+     * @param falseTransformer the transformer called if the predicate is false
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the predicate is null
-+     * @throws IllegalArgumentException if either transformer is null
-+     * @see org.apache.commons.collections15.functors.SwitchTransformer
-+     */
-+    public static <I,O> Transformer<I, O> switchTransformer(Predicate<I> predicate, Transformer<? super I, ? extends O> trueTransformer, Transformer<? super I, ? extends O> falseTransformer) {
-+        return SwitchTransformer.getInstance(new Predicate[]{predicate}, new Transformer[]{trueTransformer}, falseTransformer);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls one of the transformers depending
-+     * on the predicates. The transformer at array location 0 is called if the
-+     * predicate at array location 0 returned true. Each predicate is evaluated
-+     * until one returns true. If no predicates evaluate to true, null is returned.
-+     *
-+     * @param predicates   an array of predicates to check
-+     * @param transformers an array of transformers to call
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the either array is null
-+     * @throws IllegalArgumentException if the either array has 0 elements
-+     * @throws IllegalArgumentException if any element in the arrays is null
-+     * @throws IllegalArgumentException if the arrays are different sizes
-+     * @see org.apache.commons.collections15.functors.SwitchTransformer
-+     */
-+    public static <I,O> Transformer<I, O> switchTransformer(Predicate<? super I>[] predicates, Transformer<? super I, ? extends O>[] transformers) {
-+        return SwitchTransformer.<I, O>getInstance(predicates, transformers, null);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls one of the transformers depending
-+     * on the predicates. The transformer at array location 0 is called if the
-+     * predicate at array location 0 returned true. Each predicate is evaluated
-+     * until one returns true. If no predicates evaluate to true, the default
-+     * transformer is called. If the default transformer is null, null is returned.
-+     *
-+     * @param predicates         an array of predicates to check
-+     * @param transformers       an array of transformers to call
-+     * @param defaultTransformer the default to call if no predicate matches, null means return null
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the either array is null
-+     * @throws IllegalArgumentException if the either array has 0 elements
-+     * @throws IllegalArgumentException if any element in the arrays is null
-+     * @throws IllegalArgumentException if the arrays are different sizes
-+     * @see org.apache.commons.collections15.functors.SwitchTransformer
-+     */
-+    public static <I,O> Transformer<I, O> switchTransformer(Predicate<? super I>[] predicates, Transformer<? super I, ? extends O>[] transformers, Transformer<? super I, ? extends O> defaultTransformer) {
-+        return SwitchTransformer.<I, O>getInstance(predicates, transformers, defaultTransformer);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls one of the transformers depending
-+     * on the predicates.
-+     * <p/>
-+     * The Map consists of Predicate keys and Transformer values. A transformer
-+     * is called if its matching predicate returns true. Each predicate is evaluated
-+     * until one returns true. If no predicates evaluate to true, the default
-+     * transformer is called. The default transformer is set in the map with a
-+     * null key. If no default transformer is set, null will be returned in a default
-+     * case. The ordering is that of the iterator() method on the entryset collection
-+     * of the map.
-+     *
-+     * @param predicatesAndTransformers a map of predicates to transformers
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the map is null
-+     * @throws IllegalArgumentException if the map is empty
-+     * @throws IllegalArgumentException if any transformer in the map is null
-+     * @throws ClassCastException       if the map elements are of the wrong type
-+     * @see org.apache.commons.collections15.functors.SwitchTransformer
-+     */
-+    public static <I,O> Transformer<I, O> switchTransformer(Map<Predicate<? super I>, Transformer<? super I, ? extends O>> predicatesAndTransformers) {
-+        return SwitchTransformer.<I, O>getInstance(predicatesAndTransformers);
-+    }
-+
-+    /**
-+     * Create a new Transformer that uses the input object as a key to find the
-+     * transformer to call.
-+     * <p/>
-+     * The Map consists of object keys and Transformer values. A transformer
-+     * is called if the input object equals the key. If there is no match, the
-+     * default transformer is called. The default transformer is set in the map
-+     * using a null key. If no default is set, null will be returned in a default case.
-+     *
-+     * @param objectsAndTransformers a map of objects to transformers
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the map is null
-+     * @throws IllegalArgumentException if the map is empty
-+     * @throws IllegalArgumentException if any transformer in the map is null
-+     * @see org.apache.commons.collections15.functors.SwitchTransformer
-+     */
-+    public static <I,O> Transformer<I, O> switchMapTransformer(Map<I, Transformer<? super I, ? extends O>> objectsAndTransformers) {
-+        Transformer[] trs = null;
-+        Predicate[] preds = null;
-+        if (objectsAndTransformers == null) {
-+            throw new IllegalArgumentException("The object and transformer map must not be null");
-+        }
-+        Transformer<? super I, ? extends O> def = objectsAndTransformers.remove(null);
-+        int size = objectsAndTransformers.size();
-+        trs = new Transformer[size];
-+        preds = new Predicate[size];
-+        int i = 0;
-+        for (Iterator<Map.Entry<I, Transformer<? super I, ? extends O>>> it = objectsAndTransformers.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<I, Transformer<? super I, ? extends O>> entry = it.next();
-+            preds[i] = EqualPredicate.getInstance(entry.getKey());
-+            trs[i] = entry.getValue();
-+            i++;
-+        }
-+        return switchTransformer(preds, trs, def);
-+    }
-+
-+    /**
-+     * Gets a Transformer that expects an input Class object that it will instantiate.
-+     *
-+     * @return the transformer
-+     * @see org.apache.commons.collections15.functors.InstantiateTransformer
-+     */
-+    public static Transformer<Class, Object> instantiateTransformer() {
-+        return InstantiateTransformer.NO_ARG_INSTANCE;
-+    }
-+
-+    /**
-+     * Creates a Transformer that expects an input Class object that it will
-+     * instantiate. The constructor used is determined by the arguments specified
-+     * to this method.
-+     *
-+     * @param paramTypes parameter types for the constructor, can be null
-+     * @param args       the arguments to pass to the constructor, can be null
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the paramTypes and args don't match
-+     * @see org.apache.commons.collections15.functors.InstantiateTransformer
-+     */
-+    public static Transformer<Class, Object> instantiateTransformer(Class[] paramTypes, Object[] args) {
-+        return InstantiateTransformer.getInstance(paramTypes, args);
-+    }
-+
-+    /**
-+     * Creates a Transformer that uses the passed in Map to transform the input
-+     * object (as a simple lookup).
-+     *
-+     * @param map the map to use to transform the objects
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the map is null
-+     * @see org.apache.commons.collections15.functors.MapTransformer
-+     */
-+    public static <I,O> Transformer<I, O> mapTransformer(Map<I, O> map) {
-+        return MapTransformer.getInstance(map);
-+    }
-+
-+    /**
-+     * Gets a Transformer that invokes a method on the input object.
-+     * The method must have no parameters. If the input object is null,
-+     * null is returned.
-+     * <p/>
-+     * For example, <code>TransformerUtils.invokerTransformer("getName");</code>
-+     * will call the <code>getName/code> method on the input object to
-+     * determine the transformer result.
-+     * <p/>
-+     * Note: no type saftey provided by Java 1.5.
-+     *
-+     * @param methodName the method name to call on the input object, may not be null
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the methodName is null.
-+     * @see org.apache.commons.collections15.functors.InvokerTransformer
-+     */
-+    public static Transformer invokerTransformer(String methodName) {
-+        return InvokerTransformer.getInstance(methodName, null, null);
-+    }
-+
-+    /**
-+     * Gets a Transformer that invokes a method on the input object.
-+     * The method parameters are specified. If the input object is null,
-+     * null is returned.
-+     * <p/>
-+     * Note: no type saftey provided by Java 1.5.
-+     *
-+     * @param methodName the name of the method
-+     * @param paramTypes the parameter types
-+     * @param args       the arguments
-+     * @return the transformer
-+     * @throws IllegalArgumentException if the method name is null
-+     * @throws IllegalArgumentException if the paramTypes and args don't match
-+     * @see org.apache.commons.collections15.functors.InvokerTransformer
-+     */
-+    public static Transformer invokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
-+        return InvokerTransformer.getInstance(methodName, paramTypes, args);
-+    }
-+
-+    /**
-+     * Gets a transformer that returns a <code>java.lang.String</code>
-+     * representation of the input object. This is achieved via the
-+     * <code>toString</code> method, <code>null</code> returns 'null'.
-+     *
-+     * @return the transformer
-+     * @see org.apache.commons.collections15.functors.StringValueTransformer
-+     */
-+    public static <T> Transformer<T, String> stringValueTransformer() {
-+        return StringValueTransformer.getInstance();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/Unmodifiable.java
-@@ -0,0 +1,39 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15;
-+
-+/**
-+ * Marker interface for collections15, maps and iterators that are unmodifiable.
-+ * <p/>
-+ * This interface enables testing such as:
-+ * <pre>
-+ * if (coll instanceof Unmodifiable) {
-+ *   coll = new ArrayList(coll);
-+ * }
-+ * // now we know coll is modifiable
-+ * </pre>
-+ * Of course all this only works if you use the Unmodifiable classes defined
-+ * in this library. If you use the JDK unmodifiable class via java util Collections
-+ * then the interface won't be there.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public interface Unmodifiable {
-+    // marker interface - no methods to implement
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/AbstractBagDecorator.java
-@@ -0,0 +1,80 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.collection.AbstractCollectionDecorator;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Bag</code> to provide additional behaviour.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated bag.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractBagDecorator <E> extends AbstractCollectionDecorator<E> implements Bag<E> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractBagDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    protected AbstractBagDecorator(Bag<E> bag) {
-+        super(bag);
-+    }
-+
-+    /**
-+     * Gets the bag being decorated.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected Bag<E> getBag() {
-+        return (Bag<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public int getCount(E object) {
-+        return getBag().getCount(object);
-+    }
-+
-+    public boolean add(E object, int count) {
-+        return getBag().add(object, count);
-+    }
-+
-+    public boolean remove(E object, int count) {
-+        return getBag().remove(object, count);
-+    }
-+
-+    public Set<E> uniqueSet() {
-+        return getBag().uniqueSet();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/AbstractMapBag.java
-@@ -0,0 +1,600 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.lang.reflect.Array;
-+import java.util.*;
-+
-+/**
-+ * Abstract implementation of the {@link Bag} interface to simplify the creation
-+ * of subclass implementations.
-+ * <p/>
-+ * Subclasses specify a Map implementation to use as the internal storage.
-+ * The map will be used to map bag elements to a number; the number represents
-+ * the number of occurrences of that element in the bag.
-+ *
-+ * @author Chuck Burdick
-+ * @author Michael A. Smith
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Janek Bogucki
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0 (previously DefaultMapBag v2.0)
-+ */
-+public abstract class AbstractMapBag <E> implements Bag<E> {
-+
-+    /**
-+     * The map to use to store the data
-+     */
-+    private transient Map<E, MutableInteger> map;
-+    /**
-+     * The current total size of the bag
-+     */
-+    private int size;
-+    /**
-+     * The modification count for fail fast iterators
-+     */
-+    private transient int modCount;
-+    /**
-+     * The modification count for fail fast iterators
-+     */
-+    private transient Set<E> uniqueSet;
-+
-+    /**
-+     * Constructor needed for subclass serialisation.
-+     */
-+    protected AbstractMapBag() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that assigns the specified Map as the backing store.
-+     * The map must be empty and non-null.
-+     *
-+     * @param map the map to assign
-+     */
-+    protected AbstractMapBag(Map<E, MutableInteger> map) {
-+        super();
-+        this.map = map;
-+    }
-+
-+    /**
-+     * Utility method for implementations to access the map that backs
-+     * this bag. Not intended for interactive use outside of subclasses.
-+     *
-+     * @return the map being used by the Bag
-+     */
-+    protected Map<E, MutableInteger> getMap() {
-+        return map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the number of elements in this bag.
-+     *
-+     * @return current size of the bag
-+     */
-+    public int size() {
-+        return size;
-+    }
-+
-+    /**
-+     * Returns true if the underlying map is empty.
-+     *
-+     * @return true if bag is empty
-+     */
-+    public boolean isEmpty() {
-+        return map.isEmpty();
-+    }
-+
-+    /**
-+     * Returns the number of occurrence of the given element in this bag
-+     * by looking up its count in the underlying map.
-+     *
-+     * @param object the object to search for
-+     * @return the number of occurrences of the object, zero if not found
-+     */
-+    public int getCount(E object) {
-+        MutableInteger count = map.get(object);
-+        if (count != null) {
-+            return count.value;
-+        }
-+        return 0;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Determines if the bag contains the given element by checking if the
-+     * underlying map contains the element as a key.
-+     *
-+     * @param object the object to search for
-+     * @return true if the bag contains the given element
-+     */
-+    public boolean contains(Object object) {
-+        return map.containsKey(object);
-+    }
-+
-+    /**
-+     * Determines if the bag contains the given elements.
-+     *
-+     * @param coll the collection to check against
-+     * @return <code>true</code> if the Bag contains all the collection
-+     */
-+    public boolean containsAll(Collection<?> coll) {
-+        if (coll instanceof Bag) {
-+            return containsAll((Bag<E>) coll);
-+        }
-+        return containsAll(new HashBag(coll));
-+    }
-+
-+    /**
-+     * Returns <code>true</code> if the bag contains all elements in
-+     * the given collection, respecting cardinality.
-+     *
-+     * @param other the bag to check against
-+     * @return <code>true</code> if the Bag contains all the collection
-+     */
-+    boolean containsAll(Bag<E> other) {
-+        boolean result = true;
-+        Iterator<E> it = other.uniqueSet().iterator();
-+        while (it.hasNext()) {
-+            E current = it.next();
-+            boolean contains = getCount(current) >= other.getCount(current);
-+            result = result && contains;
-+        }
-+        return result;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator over the bag elements.
-+     * Elements present in the Bag more than once will be returned repeatedly.
-+     *
-+     * @return the iterator
-+     */
-+    public Iterator<E> iterator() {
-+        return new BagIterator<E>(this);
-+    }
-+
-+    /**
-+     * Inner class iterator for the Bag.
-+     */
-+    static class BagIterator <E> implements Iterator<E> {
-+        private AbstractMapBag<E> parent;
-+        private Iterator<Map.Entry<E, MutableInteger>> entryIterator;
-+        private Map.Entry<E, MutableInteger> current;
-+        private int itemCount;
-+        private final int mods;
-+        private boolean canRemove;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param parent the parent bag
-+         */
-+        public BagIterator(AbstractMapBag<E> parent) {
-+            this.parent = parent;
-+            this.entryIterator = parent.map.entrySet().iterator();
-+            this.current = null;
-+            this.mods = parent.modCount;
-+            this.canRemove = false;
-+        }
-+
-+        public boolean hasNext() {
-+            return (itemCount > 0 || entryIterator.hasNext());
-+        }
-+
-+        public E next() {
-+            if (parent.modCount != mods) {
-+                throw new ConcurrentModificationException();
-+            }
-+            if (itemCount == 0) {
-+                current = entryIterator.next();
-+                itemCount = current.getValue().value;
-+            }
-+            canRemove = true;
-+            itemCount--;
-+            return current.getKey();
-+        }
-+
-+        public void remove() {
-+            if (parent.modCount != mods) {
-+                throw new ConcurrentModificationException();
-+            }
-+            if (canRemove == false) {
-+                throw new IllegalStateException();
-+            }
-+            MutableInteger mut = current.getValue();
-+            if (mut.value > 0) {
-+                mut.value--;
-+                parent.size--;
-+            } else {
-+                entryIterator.remove();
-+            }
-+            canRemove = false;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Adds a new element to the bag, incrementing its count in the underlying map.
-+     *
-+     * @param object the object to add
-+     * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
-+     */
-+    public boolean add(E object) {
-+        return add(object, 1);
-+    }
-+
-+    /**
-+     * Adds a new element to the bag, incrementing its count in the map.
-+     *
-+     * @param object  the object to search for
-+     * @param nCopies the number of copies to add
-+     * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
-+     */
-+    public boolean add(E object, int nCopies) {
-+        modCount++;
-+        if (nCopies > 0) {
-+            MutableInteger mut = map.get(object);
-+            size += nCopies;
-+            if (mut == null) {
-+                map.put(object, new MutableInteger(nCopies));
-+                return true;
-+            } else {
-+                mut.value += nCopies;
-+                return false;
-+            }
-+        } else {
-+            return false;
-+        }
-+    }
-+
-+    /**
-+     * Invokes {@link #add(Object)} for each element in the given collection.
-+     *
-+     * @param coll the collection to add
-+     * @return <code>true</code> if this call changed the bag
-+     */
-+    public boolean addAll(Collection<? extends E> coll) {
-+        boolean changed = false;
-+        Iterator<? extends E> i = coll.iterator();
-+        while (i.hasNext()) {
-+            boolean added = add(i.next());
-+            changed = changed || added;
-+        }
-+        return changed;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clears the bag by clearing the underlying map.
-+     */
-+    public void clear() {
-+        modCount++;
-+        map.clear();
-+        size = 0;
-+    }
-+
-+    /**
-+     * Removes all copies of the specified object from the bag.
-+     *
-+     * @param object the object to remove
-+     * @return true if the bag changed
-+     */
-+    public boolean remove(Object object) {
-+        MutableInteger mut = map.get(object);
-+        if (mut == null) {
-+            return false;
-+        }
-+        modCount++;
-+        map.remove(object);
-+        size -= mut.value;
-+        return true;
-+    }
-+
-+    /**
-+     * Removes a specified number of copies of an object from the bag.
-+     *
-+     * @param object  the object to remove
-+     * @param nCopies the number of copies to remove
-+     * @return true if the bag changed
-+     */
-+    public boolean remove(E object, int nCopies) {
-+        MutableInteger mut = map.get(object);
-+        if (mut == null) {
-+            return false;
-+        }
-+        if (nCopies <= 0) {
-+            return false;
-+        }
-+        modCount++;
-+        if (nCopies < mut.value) {
-+            mut.value -= nCopies;
-+            map.put(object, mut);
-+            size -= nCopies;
-+        } else {
-+            map.remove(object);
-+            size -= mut.value;
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Removes objects from the bag according to their count in the specified collection.
-+     *
-+     * @param coll the collection to use
-+     * @return true if the bag changed
-+     */
-+    public boolean removeAll(Collection<?> coll) {
-+        boolean result = false;
-+        if (coll != null) {
-+            Iterator i = coll.iterator();
-+            while (i.hasNext()) {
-+                boolean changed = remove((E) i.next(), 1);
-+                result = result || changed;
-+            }
-+        }
-+        return result;
-+    }
-+
-+    /**
-+     * Remove any members of the bag that are not in the given
-+     * bag, respecting cardinality.
-+     *
-+     * @param coll the collection to retain
-+     * @return true if this call changed the collection
-+     */
-+    public boolean retainAll(Collection<?> coll) {
-+        if (coll instanceof Bag) {
-+            return retainAll((Bag<? extends E>) coll);
-+        }
-+        return retainAll(new HashBag(coll));
-+    }
-+
-+    /**
-+     * Remove any members of the bag that are not in the given
-+     * bag, respecting cardinality.
-+     *
-+     * @param other the bag to retain
-+     * @return <code>true</code> if this call changed the collection
-+     * @see #retainAll(Collection)
-+     */
-+    boolean retainAll(Bag<E> other) {
-+        boolean result = false;
-+        Bag excess = new HashBag();
-+        Iterator<E> i = uniqueSet().iterator();
-+        while (i.hasNext()) {
-+            E current = i.next();
-+            int myCount = getCount(current);
-+            int otherCount = other.getCount(current);
-+            if (1 <= otherCount && otherCount <= myCount) {
-+                excess.add(current, myCount - otherCount);
-+            } else {
-+                excess.add(current, myCount);
-+            }
-+        }
-+        if (!excess.isEmpty()) {
-+            result = removeAll(excess);
-+        }
-+        return result;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+
-+    /**
-+     * Mutable integer class for storing the data.
-+     */
-+    protected static class MutableInteger {
-+        /**
-+         * The value of this mutable.
-+         */
-+        protected int value;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param value the initial value
-+         */
-+        MutableInteger(int value) {
-+            this.value = value;
-+        }
-+
-+        public boolean equals(Object obj) {
-+            if (obj instanceof MutableInteger == false) {
-+                return false;
-+            }
-+            return ((MutableInteger) obj).value == value;
-+        }
-+
-+        public int hashCode() {
-+            return value;
-+        }
-+    }
-+
-+    /**
-+     * Returns an array of all of this bag's elements.
-+     *
-+     * @return an array of all of this bag's elements
-+     */
-+    public Object[] toArray() {
-+        Object[] result = new Object[size()];
-+        int i = 0;
-+        Iterator<E> it = map.keySet().iterator();
-+        while (it.hasNext()) {
-+            E current = it.next();
-+            for (int index = getCount(current); index > 0; index--) {
-+                result[i++] = current;
-+            }
-+        }
-+        return result;
-+    }
-+
-+    /**
-+     * Returns an array of all of this bag's elements.
-+     *
-+     * @param array the array to populate
-+     * @return an array of all of this bag's elements
-+     */
-+    public Object[] toArray(Object[] array) {
-+        int size = size();
-+        if (array.length < size) {
-+            array = (Object[]) Array.newInstance(array.getClass().getComponentType(), size);
-+        }
-+
-+        int i = 0;
-+        Iterator<E> it = map.keySet().iterator();
-+        while (it.hasNext()) {
-+            E current = it.next();
-+            for (int index = getCount(current); index > 0; index--) {
-+                array[i++] = current;
-+            }
-+        }
-+        if (array.length > size) {
-+            array[size] = null;
-+        }
-+        return array;
-+    }
-+
-+    /**
-+     * Returns an unmodifiable view of the underlying map's key set.
-+     *
-+     * @return the set of unique elements in this bag
-+     */
-+    public Set<E> uniqueSet() {
-+        if (uniqueSet == null) {
-+            uniqueSet = UnmodifiableSet.decorate(map.keySet());
-+        }
-+        return uniqueSet;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    protected void doWriteObject(ObjectOutputStream out) throws IOException {
-+        out.writeInt(map.size());
-+        for (Iterator<Map.Entry<E, MutableInteger>> it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<E, MutableInteger> entry = it.next();
-+            out.writeObject(entry.getKey());
-+            out.writeInt(entry.getValue().value);
-+        }
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param map the map to use
-+     * @param in  the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    protected void doReadObject(Map<E, MutableInteger> map, ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        this.map = map;
-+        int entrySize = in.readInt();
-+        for (int i = 0; i < entrySize; i++) {
-+            E obj = (E) in.readObject();
-+            int count = in.readInt();
-+            map.put(obj, new MutableInteger(count));
-+            size += count;
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares this Bag to another.
-+     * This Bag equals another Bag if it contains the same number of occurrences of
-+     * the same elements.
-+     *
-+     * @param object the Bag to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object object) {
-+        if (object == this) {
-+            return true;
-+        }
-+        if (object instanceof Bag == false) {
-+            return false;
-+        }
-+        Bag other = (Bag) object;
-+        if (other.size() != size()) {
-+            return false;
-+        }
-+        for (Iterator<E> it = map.keySet().iterator(); it.hasNext();) {
-+            E element = it.next();
-+            if (other.getCount(element) != getCount(element)) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Gets a hash code for the Bag compatible with the definition of equals.
-+     * The hash code is defined as the sum total of a hash code for each element.
-+     * The per element hash code is defined as
-+     * <code>(e==null ? 0 : e.hashCode()) ^ noOccurances)</code>.
-+     * This hash code is compatible with the Set interface.
-+     *
-+     * @return the hash code of the Bag
-+     */
-+    public int hashCode() {
-+        int total = 0;
-+        for (Iterator<Map.Entry<E, MutableInteger>> it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<E, MutableInteger> entry = it.next();
-+            Object element = entry.getKey();
-+            Integer count = entry.getValue().value;
-+            total += (element == null ? 0 : element.hashCode()) ^ count;
-+        }
-+        return total;
-+    }
-+
-+    /**
-+     * Implement a toString() method suitable for debugging.
-+     *
-+     * @return a debugging toString
-+     */
-+    public String toString() {
-+        if (size() == 0) {
-+            return "[]";
-+        }
-+        StringBuffer buf = new StringBuffer();
-+        buf.append('[');
-+        Iterator<E> it = uniqueSet().iterator();
-+        while (it.hasNext()) {
-+            E current = it.next();
-+            int count = getCount(current);
-+            buf.append(count);
-+            buf.append(':');
-+            buf.append(current);
-+            if (it.hasNext()) {
-+                buf.append(',');
-+            }
-+        }
-+        buf.append(']');
-+        return buf.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/AbstractSortedBagDecorator.java
-@@ -0,0 +1,75 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.SortedBag;
-+
-+import java.util.Comparator;
-+
-+/**
-+ * Decorates another <code>SortedBag</code> to provide additional behaviour.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated bag.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractSortedBagDecorator <E> extends AbstractBagDecorator<E> implements SortedBag<E> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractSortedBagDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    protected AbstractSortedBagDecorator(SortedBag<E> bag) {
-+        super(bag);
-+    }
-+
-+    /**
-+     * Gets the bag being decorated.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected SortedBag<E> getSortedBag() {
-+        return (SortedBag<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E first() {
-+        return getSortedBag().first();
-+    }
-+
-+    public E last() {
-+        return getSortedBag().last();
-+    }
-+
-+    public Comparator<? super E> comparator() {
-+        return getSortedBag().comparator();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/HashBag.java
-@@ -0,0 +1,84 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.HashMap;
-+
-+/**
-+ * Implements <code>Bag</code>, using a <code>HashMap</code> to provide the
-+ * data storage. This is the standard implementation of a bag.
-+ * <p/>
-+ * A <code>Bag</code> stores each object in the collection together with a
-+ * count of occurrences. Extra methods on the interface allow multiple copies
-+ * of an object to be added or removed at once. It is important to read the
-+ * interface javadoc carefully as several methods violate the
-+ * <code>Collection</code> interface specification.
-+ *
-+ * @author Chuck Burdick
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0 (previously in main package v2.0)
-+ */
-+public class HashBag <E> extends AbstractMapBag<E> implements Bag<E>, Serializable {
-+
-+    /**
-+     * Serial version lock
-+     */
-+    static final long serialVersionUID = -6561115435802554013L;
-+
-+    /**
-+     * Constructs an empty <code>HashBag</code>.
-+     */
-+    public HashBag() {
-+        super(new HashMap<E, MutableInteger>());
-+    }
-+
-+    /**
-+     * Constructs a bag containing all the members of the given collection.
-+     *
-+     * @param coll a collection to copy into this bag
-+     */
-+    public HashBag(Collection<? extends E> coll) {
-+        this();
-+        addAll(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the bag out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        super.doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the bag in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        super.doReadObject(new HashMap<E, MutableInteger>(), in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/PredicatedBag.java
-@@ -0,0 +1,109 @@
-+// GenericsNotes: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.collection.PredicatedCollection;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Bag</code> to validate that additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This bag exists to provide validation for the decorated bag.
-+ * It is normally created to decorate an empty bag.
-+ * If an object cannot be added to the bag, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null entries are added to the bag.
-+ * <pre>Bag bag = PredicatedBag.decorate(new HashBag(), NotNullPredicate.INSTANCE);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedBag <E> extends PredicatedCollection<E> implements Bag<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -2575833140344736876L;
-+
-+    /**
-+     * Factory method to create a predicated (validating) bag.
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are validated.
-+     *
-+     * @param bag       the bag to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @return a new predicated Bag
-+     * @throws IllegalArgumentException if bag or predicate is null
-+     * @throws IllegalArgumentException if the bag contains invalid elements
-+     */
-+    public static <E> Bag<E> decorate(Bag<E> bag, Predicate<? super E> predicate) {
-+        return new PredicatedBag<E>(bag, predicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are validated.
-+     *
-+     * @param bag       the bag to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if bag or predicate is null
-+     * @throws IllegalArgumentException if the bag contains invalid elements
-+     */
-+    protected PredicatedBag(Bag<E> bag, Predicate<? super E> predicate) {
-+        super(bag, predicate);
-+    }
-+
-+    /**
-+     * Gets the decorated bag.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected Bag<E> getBag() {
-+        return (Bag<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E object, int count) {
-+        validate(object);
-+        return getBag().add(object, count);
-+    }
-+
-+    public boolean remove(E object, int count) {
-+        return getBag().remove(object, count);
-+    }
-+
-+    public Set uniqueSet() {
-+        return getBag().uniqueSet();
-+    }
-+
-+    public int getCount(E object) {
-+        return getBag().getCount(object);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/PredicatedSortedBag.java
-@@ -0,0 +1,103 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.SortedBag;
-+
-+import java.util.Comparator;
-+
-+/**
-+ * Decorates another <code>SortedBag</code> to validate that additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This bag exists to provide validation for the decorated bag.
-+ * It is normally created to decorate an empty bag.
-+ * If an object cannot be added to the bag, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null entries are added to the bag.
-+ * <pre>SortedBag bag = PredicatedSortedBag.decorate(new TreeBag(), NotNullPredicate.INSTANCE);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedSortedBag <E> extends PredicatedBag<E> implements SortedBag<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 3448581314086406616L;
-+
-+    /**
-+     * Factory method to create a predicated (validating) bag.
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are validated.
-+     *
-+     * @param bag       the bag to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @return a new predicated SortedBag
-+     * @throws IllegalArgumentException if bag or predicate is null
-+     * @throws IllegalArgumentException if the bag contains invalid elements
-+     */
-+    public static <E> SortedBag<E> decorate(SortedBag<E> bag, Predicate<? super E> predicate) {
-+        return new PredicatedSortedBag(bag, predicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are validated.
-+     *
-+     * @param bag       the bag to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if bag or predicate is null
-+     * @throws IllegalArgumentException if the bag contains invalid elements
-+     */
-+    protected PredicatedSortedBag(SortedBag<E> bag, Predicate<? super E> predicate) {
-+        super(bag, predicate);
-+    }
-+
-+    /**
-+     * Gets the decorated sorted bag.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected SortedBag<E> getSortedBag() {
-+        return (SortedBag<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E first() {
-+        return getSortedBag().first();
-+    }
-+
-+    public E last() {
-+        return getSortedBag().last();
-+    }
-+
-+    public Comparator<? super E> comparator() {
-+        return getSortedBag().comparator();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/SynchronizedBag.java
-@@ -0,0 +1,129 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.collection.SynchronizedCollection;
-+import org.apache.commons.collections15.set.SynchronizedSet;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Bag</code> to synchronize its behaviour
-+ * for a multi-threaded environment.
-+ * <p/>
-+ * Methods are synchronized, then forwarded to the decorated bag.
-+ * Iterators must be separately synchronized around the loop.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SynchronizedBag <E> extends SynchronizedCollection<E> implements Bag<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 8084674570753837109L;
-+
-+    /**
-+     * Factory method to create a synchronized bag.
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @return a new synchronized Bag
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    public static <E> Bag<E> decorate(Bag<E> bag) {
-+        return new SynchronizedBag<E>(bag);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    protected SynchronizedBag(Bag<E> bag) {
-+        super(bag);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag  the bag to decorate, must not be null
-+     * @param lock the lock to use, must not be null
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    protected SynchronizedBag(Bag<E> bag, Object lock) {
-+        super(bag, lock);
-+    }
-+
-+    /**
-+     * Gets the bag being decorated.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected Bag<E> getBag() {
-+        return (Bag<E>) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E object, int count) {
-+        synchronized (lock) {
-+            return getBag().add(object, count);
-+        }
-+    }
-+
-+    public boolean remove(E object, int count) {
-+        synchronized (lock) {
-+            return getBag().remove(object, count);
-+        }
-+    }
-+
-+    public Set<E> uniqueSet() {
-+        synchronized (lock) {
-+            Set<E> set = getBag().uniqueSet();
-+            return new SynchronizedBagSet(set, lock);
-+        }
-+    }
-+
-+    public int getCount(E object) {
-+        synchronized (lock) {
-+            return getBag().getCount(object);
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Synchronized Set for the Bag class.
-+     */
-+    class SynchronizedBagSet extends SynchronizedSet<E> {
-+        /**
-+         * Constructor.
-+         *
-+         * @param set  the set to decorate
-+         * @param lock the lock to use, shared with the bag
-+         */
-+        SynchronizedBagSet(Set<E> set, Object lock) {
-+            super(set, lock);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/SynchronizedSortedBag.java
-@@ -0,0 +1,105 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.SortedBag;
-+
-+import java.util.Comparator;
-+
-+/**
-+ * Decorates another <code>SortedBag</code> to synchronize its behaviour
-+ * for a multi-threaded environment.
-+ * <p/>
-+ * Methods are synchronized, then forwarded to the decorated bag.
-+ * Iterators must be separately synchronized around the loop.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SynchronizedSortedBag <E> extends SynchronizedBag<E> implements SortedBag<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 722374056718497858L;
-+
-+    /**
-+     * Factory method to create a synchronized sorted bag.
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @return a new synchronized SortedBag
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    public static <E> SortedBag<E> decorate(SortedBag<E> bag) {
-+        return new SynchronizedSortedBag<E>(bag);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    protected SynchronizedSortedBag(SortedBag<E> bag) {
-+        super(bag);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag  the bag to decorate, must not be null
-+     * @param lock the lock to use, must not be null
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    protected SynchronizedSortedBag(Bag<E> bag, Object lock) {
-+        super(bag, lock);
-+    }
-+
-+    /**
-+     * Gets the bag being decorated.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected SortedBag<E> getSortedBag() {
-+        return (SortedBag<E>) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public synchronized E first() {
-+        synchronized (lock) {
-+            return getSortedBag().first();
-+        }
-+    }
-+
-+    public synchronized E last() {
-+        synchronized (lock) {
-+            return getSortedBag().last();
-+        }
-+    }
-+
-+    public synchronized Comparator<? super E> comparator() {
-+        synchronized (lock) {
-+            return getSortedBag().comparator();
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/TransformedBag.java
-@@ -0,0 +1,108 @@
-+// TODO: Not yet converted - deprecated (by me).
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.Transformer;
-+import org.apache.commons.collections15.collection.TransformedCollection;
-+import org.apache.commons.collections15.set.TransformedSet;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Bag</code> to transform objects that are added.
-+ * <p/>
-+ * The add methods are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Collection contract.
-+ *
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedBag extends TransformedCollection implements Bag {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 5421170911299074185L;
-+
-+    /**
-+     * Factory method to create a transforming bag.
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param bag         the bag to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @return a new transformed Bag
-+     * @throws IllegalArgumentException if bag or transformer is null
-+     */
-+    public static <I,O> Bag<O> decorate(Bag<I> bag, Transformer<? super I, ? extends O> transformer) {
-+        return new TransformedBag(bag, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param bag         the bag to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if bag or transformer is null
-+     */
-+    protected TransformedBag(Bag bag, Transformer transformer) {
-+        super(bag, transformer);
-+    }
-+
-+    /**
-+     * Gets the decorated bag.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected Bag getBag() {
-+        return (Bag) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public int getCount(Object object) {
-+        return getBag().getCount(object);
-+    }
-+
-+    public boolean remove(Object object, int nCopies) {
-+        return getBag().remove(object, nCopies);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(Object object, int nCopies) {
-+        object = transform(object);
-+        return getBag().add(object, nCopies);
-+    }
-+
-+    public Set uniqueSet() {
-+        Set set = getBag().uniqueSet();
-+        return TransformedSet.decorate(set, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/TransformedSortedBag.java
-@@ -0,0 +1,99 @@
-+// TODO: Not yet converted - deprecated (by me).
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.SortedBag;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.Comparator;
-+
-+/**
-+ * Decorates another <code>SortedBag</code> to transform objects that are added.
-+ * <p/>
-+ * The add methods are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Collection contract.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedSortedBag extends TransformedBag implements SortedBag {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -251737742649401930L;
-+
-+    /**
-+     * Factory method to create a transforming sorted bag.
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param bag         the bag to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @return a new transformed SortedBag
-+     * @throws IllegalArgumentException if bag or transformer is null
-+     */
-+    public static <I,O> SortedBag<O> decorate(SortedBag<I> bag, Transformer<? super I, ? extends O> transformer) {
-+        return new TransformedSortedBag(bag, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param bag         the bag to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if bag or transformer is null
-+     */
-+    protected TransformedSortedBag(SortedBag bag, Transformer transformer) {
-+        super(bag, transformer);
-+    }
-+
-+    /**
-+     * Gets the decorated bag.
-+     *
-+     * @return the decorated bag
-+     */
-+    protected SortedBag getSortedBag() {
-+        return (SortedBag) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Object first() {
-+        return getSortedBag().first();
-+    }
-+
-+    public Object last() {
-+        return getSortedBag().last();
-+    }
-+
-+    public Comparator comparator() {
-+        return getSortedBag().comparator();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/TreeBag.java
-@@ -0,0 +1,115 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.SortedBag;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Comparator;
-+import java.util.SortedMap;
-+import java.util.TreeMap;
-+
-+/**
-+ * Implements <code>SortedBag</code>, using a <code>TreeMap</code> to provide
-+ * the data storage. This is the standard implementation of a sorted bag.
-+ * <p/>
-+ * Order will be maintained among the bag members and can be viewed through the
-+ * iterator.
-+ * <p/>
-+ * A <code>Bag</code> stores each object in the collection together with a
-+ * count of occurrences. Extra methods on the interface allow multiple copies
-+ * of an object to be added or removed at once. It is important to read the
-+ * interface javadoc carefully as several methods violate the
-+ * <code>Collection</code> interface specification.
-+ *
-+ * @author Matt Hall, John Watkinson, Chuck Burdick
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0 (previously in main package v2.0)
-+ */
-+public class TreeBag <E> extends AbstractMapBag<E> implements SortedBag<E>, Serializable {
-+
-+    /**
-+     * Serial version lock
-+     */
-+    static final long serialVersionUID = -7740146511091606676L;
-+
-+    /**
-+     * Constructs an empty <code>TreeBag</code>.
-+     */
-+    public TreeBag() {
-+        super(new TreeMap<E, MutableInteger>());
-+    }
-+
-+    /**
-+     * Constructs an empty bag that maintains order on its unique
-+     * representative members according to the given {@link Comparator}.
-+     *
-+     * @param comparator the comparator to use
-+     */
-+    public TreeBag(Comparator<? super E> comparator) {
-+        super(new TreeMap<E, MutableInteger>(comparator));
-+    }
-+
-+    /**
-+     * Constructs a <code>TreeBag</code> containing all the members of the
-+     * specified collection.
-+     *
-+     * @param coll the collection to copy into the bag
-+     */
-+    public TreeBag(Collection<? extends E> coll) {
-+        this();
-+        addAll(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E first() {
-+        return ((SortedMap<E, MutableInteger>) getMap()).firstKey();
-+    }
-+
-+    public E last() {
-+        return ((SortedMap<E, MutableInteger>) getMap()).lastKey();
-+    }
-+
-+    public Comparator comparator() {
-+        return ((SortedMap) getMap()).comparator();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the bag out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(comparator());
-+        super.doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the bag in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        Comparator comp = (Comparator) in.readObject();
-+        super.doReadObject(new TreeMap<E, MutableInteger>(comp), in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/TypedBag.java
-@@ -0,0 +1,61 @@
-+// GenericsNote: Deprecated and not coverted, type safety not necessary anymore.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+/**
-+ * Decorates another <code>Bag</code> to validate that elements added
-+ * are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ * @deprecated Type safety classes not required anymore under 1.5, just use a typed Bag.
-+ */
-+public class TypedBag {
-+
-+    /**
-+     * Factory method to create a typed bag.
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are validated.
-+     *
-+     * @param bag  the bag to decorate, must not be null
-+     * @param type the type to allow into the bag, must not be null
-+     * @return a new typed Bag
-+     * @throws IllegalArgumentException if bag or type is null
-+     * @throws IllegalArgumentException if the bag contains invalid elements
-+     */
-+    public static Bag decorate(Bag bag, Class type) {
-+        return new PredicatedBag(bag, InstanceofPredicate.getInstance(type));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedBag() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/TypedSortedBag.java
-@@ -0,0 +1,60 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.SortedBag;
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+/**
-+ * Decorates another <code>SortedBag</code> to validate that elements added
-+ * are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TypedSortedBag <E> {
-+
-+    /**
-+     * Factory method to create a typed sorted bag.
-+     * <p/>
-+     * If there are any elements already in the bag being decorated, they
-+     * are validated.
-+     *
-+     * @param bag  the bag to decorate, must not be null
-+     * @param type the type to allow into the bag, must not be null
-+     * @return a new transformed SortedBag
-+     * @throws IllegalArgumentException if bag or type is null
-+     * @throws IllegalArgumentException if the bag contains invalid elements
-+     */
-+    public static <E> SortedBag<E> decorate(SortedBag<E> bag, Class<E> type) {
-+        return new PredicatedSortedBag<E>(bag, InstanceofPredicate.getInstance(type));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedSortedBag() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/UnmodifiableBag.java
-@@ -0,0 +1,142 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.Bag;
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Bag</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableBag <E> extends AbstractBagDecorator<E> implements Unmodifiable, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -1873799975157099624L;
-+
-+    /**
-+     * Factory method to create an unmodifiable bag.
-+     * <p/>
-+     * If the bag passed in is already unmodifiable, it is returned.
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @return an unmodifiable Bag
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    public static <E> Bag<E> decorate(Bag<E> bag) {
-+        if (bag instanceof Unmodifiable) {
-+            return bag;
-+        }
-+        return new UnmodifiableBag<E>(bag);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    private UnmodifiableBag(Bag<E> bag) {
-+        super(bag);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the collection out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(collection);
-+    }
-+
-+    /**
-+     * Read the collection in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        collection = (Collection<E>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E object, int count) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(E object, int count) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public Set<E> uniqueSet() {
-+        Set<E> set = getBag().uniqueSet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/UnmodifiableSortedBag.java
-@@ -0,0 +1,142 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bag;
-+
-+import org.apache.commons.collections15.SortedBag;
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>SortedBag</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableSortedBag <E> extends AbstractSortedBagDecorator<E> implements Unmodifiable, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -3190437252665717841L;
-+
-+    /**
-+     * Factory method to create an unmodifiable bag.
-+     * <p/>
-+     * If the bag passed in is already unmodifiable, it is returned.
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @return an unmodifiable SortedBag
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    public static <E> SortedBag<E> decorate(SortedBag<E> bag) {
-+        if (bag instanceof Unmodifiable) {
-+            return bag;
-+        }
-+        return new UnmodifiableSortedBag<E>(bag);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param bag the bag to decorate, must not be null
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    private UnmodifiableSortedBag(SortedBag<E> bag) {
-+        super(bag);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the collection out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(collection);
-+    }
-+
-+    /**
-+     * Read the collection in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        collection = (Collection<E>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E object, int count) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(E object, int count) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public Set<E> uniqueSet() {
-+        Set<E> set = getBag().uniqueSet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bag/package.html
-@@ -0,0 +1,39 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:19 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link org.apache.commons.collections.Bag Bag} and 
-+{@link org.apache.commons.collections.SortedBag SortedBag} interfaces.
-+A bag stores an object and a count of the number of occurences of the object.
-+<p>
-+The following implementations are provided in the package:
-+<ul>
-+<li>HashBag - implementation that uses a HashMap to store the data
-+<li>TreeBag - implementation that uses a TreeMap to store the data
-+</ul>
-+<p>
-+The following decorators are provided in the package:
-+<ul>
-+<li>Synchronized - synchronizes method access for multi-threaded environments
-+<li>Unmodifiable - ensures the bag cannot be altered
-+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
-+<li>Typed - ensures that only elements that are of a specific type can be added
-+<li>Transformed - transforms each element added to the bag
-+</ul>
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/AbstractBidiMapDecorator.java
-@@ -0,0 +1,82 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.BidiMap;
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.map.AbstractMapDecorator;
-+
-+import java.util.Set;
-+
-+/**
-+ * Provides a base decorator that enables additional functionality to be added
-+ * to a BidiMap via decoration.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated map.
-+ * <p/>
-+ * This implementation does not perform any special processing with the map views.
-+ * Instead it simply returns the set/collection from the wrapped map. This may be
-+ * undesirable, for example if you are trying to write a validating implementation
-+ * it would provide a loophole around the validation.
-+ * But, you might want that loophole, so this class is kept simple.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractBidiMapDecorator <K,V> extends AbstractMapDecorator<K, V> implements BidiMap<K, V> {
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    protected AbstractBidiMapDecorator(BidiMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected BidiMap<K, V> getBidiMap() {
-+        return (BidiMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public MapIterator<K, V> mapIterator() {
-+        return getBidiMap().mapIterator();
-+    }
-+
-+    public K getKey(Object value) {
-+        return getBidiMap().getKey(value);
-+    }
-+
-+    public K removeValue(Object value) {
-+        return getBidiMap().removeValue(value);
-+    }
-+
-+    public BidiMap<V, K> inverseBidiMap() {
-+        return getBidiMap().inverseBidiMap();
-+    }
-+
-+    public Set<V> values() {
-+        return getBidiMap().values();
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/AbstractDualBidiMap.java
-@@ -0,0 +1,762 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.BidiMap;
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.ResettableIterator;
-+import org.apache.commons.collections15.collection.AbstractCollectionDecorator;
-+import org.apache.commons.collections15.iterators.AbstractIteratorDecorator;
-+import org.apache.commons.collections15.keyvalue.AbstractMapEntryDecorator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Abstract <code>BidiMap</code> implemented using two maps.
-+ * <p/>
-+ * An implementation can be written simply by implementing the
-+ * <code>createMap</code> method.
-+ *
-+ * @author Matthew Hawthorne
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Id: AbstractDualBidiMap.java,v 1.1 2005/10/11 17:05:19 pents90 Exp $
-+ * @see DualHashBidiMap
-+ * @see DualTreeBidiMap
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractDualBidiMap <K,V> implements BidiMap<K, V> {
-+
-+    /**
-+     * Delegate maps.  The first map contains standard entries, and the
-+     * second contains inverses.
-+     */
-+    protected transient Map<K, V> forwardMap;
-+    protected transient Map<V, K> inverseMap;
-+
-+    /**
-+     * Inverse view of this map.
-+     */
-+    protected transient BidiMap<V, K> inverseBidiMap = null;
-+    /**
-+     * View of the keys.
-+     */
-+    protected transient Set<K> keySet = null;
-+    /**
-+     * View of the values.
-+     */
-+    protected transient Set<V> values = null;
-+    /**
-+     * View of the entries.
-+     */
-+    protected transient Set<Map.Entry<K, V>> entrySet = null;
-+
-+    /**
-+     * Creates an empty map, initialised by <code>createMap</code>.
-+     * <p/>
-+     * This constructor remains in place for deserialization.
-+     * All other usage is deprecated in favour of
-+     * {@link #AbstractDualBidiMap(Map, Map)}.
-+     *
-+     * @deprecated should not be used.
-+     */
-+    protected AbstractDualBidiMap() {
-+        super();
-+        forwardMap = createMap();
-+        inverseMap = createMap();
-+    }
-+
-+    /**
-+     * Creates an empty map using the two maps specified as storage.
-+     * <p/>
-+     * The two maps must be a matching pair, normal and reverse.
-+     * They will typically both be empty.
-+     * <p/>
-+     * Neither map is validated, so nulls may be passed in.
-+     * If you choose to do this then the subclass constructor must populate
-+     * the <code>maps[]</code> instance variable itself.
-+     *
-+     * @param normalMap  the normal direction map
-+     * @param reverseMap the reverse direction map
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractDualBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap) {
-+        super();
-+        forwardMap = normalMap;
-+        inverseMap = reverseMap;
-+    }
-+
-+    /**
-+     * Constructs a map that decorates the specified maps,
-+     * used by the subclass <code>createBidiMap</code> implementation.
-+     *
-+     * @param normalMap      the normal direction map
-+     * @param reverseMap     the reverse direction map
-+     * @param inverseBidiMap the inverse BidiMap
-+     */
-+    protected AbstractDualBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseBidiMap) {
-+        super();
-+        forwardMap = normalMap;
-+        inverseMap = reverseMap;
-+        this.inverseBidiMap = inverseBidiMap;
-+    }
-+
-+    /**
-+     * Creates a new instance of the map used by the subclass to store data.
-+     * <p/>
-+     * This design is deeply flawed and has been deprecated.
-+     * It relied on subclass data being used during a superclass constructor.
-+     *
-+     * @return the map to be used for internal storage
-+     * @deprecated For constructors, use the new two map constructor.
-+     *             For deserialization, populate the maps array directly in readObject.
-+     */
-+    protected Map createMap() {
-+        return null;
-+    }
-+
-+    /**
-+     * Creates a new instance of the subclass.
-+     *
-+     * @param normalMap  the normal direction map
-+     * @param reverseMap the reverse direction map
-+     * @param inverseMap this map, which is the inverse in the new map
-+     * @return the inverse map
-+     */
-+    protected abstract <K,V> BidiMap<K, V> createBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseMap);
-+
-+    // Map delegation
-+    //-----------------------------------------------------------------------
-+    public V get(Object key) {
-+        return forwardMap.get(key);
-+    }
-+
-+    public int size() {
-+        return forwardMap.size();
-+    }
-+
-+    public boolean isEmpty() {
-+        return forwardMap.isEmpty();
-+    }
-+
-+    public boolean containsKey(Object key) {
-+        return forwardMap.containsKey(key);
-+    }
-+
-+    public boolean equals(Object obj) {
-+        return forwardMap.equals(obj);
-+    }
-+
-+    public int hashCode() {
-+        return forwardMap.hashCode();
-+    }
-+
-+    public String toString() {
-+        return forwardMap.toString();
-+    }
-+
-+    // BidiMap changes
-+    //-----------------------------------------------------------------------
-+    public V put(K key, V value) {
-+        if (forwardMap.containsKey(key)) {
-+            inverseMap.remove(forwardMap.get(key));
-+        }
-+        if (inverseMap.containsKey(value)) {
-+            forwardMap.remove(inverseMap.get(value));
-+        }
-+        final V obj = forwardMap.put(key, value);
-+        inverseMap.put(value, key);
-+        return obj;
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            put((K) entry.getKey(), (V) entry.getValue());
-+        }
-+    }
-+
-+    public V remove(Object key) {
-+        V value = null;
-+        if (forwardMap.containsKey(key)) {
-+            value = forwardMap.remove(key);
-+            inverseMap.remove(value);
-+        }
-+        return value;
-+    }
-+
-+    public void clear() {
-+        forwardMap.clear();
-+        inverseMap.clear();
-+    }
-+
-+    public boolean containsValue(Object value) {
-+        return inverseMap.containsKey(value);
-+    }
-+
-+    // BidiMap
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Obtains a <code>MapIterator</code> over the map.
-+     * The iterator implements <code>ResetableMapIterator</code>.
-+     * This implementation relies on the entrySet iterator.
-+     * <p/>
-+     * The setValue() methods only allow a new value to be set.
-+     * If the value being set is already in the map, an IllegalArgumentException
-+     * is thrown (as setValue cannot change the size of the map).
-+     *
-+     * @return a map iterator
-+     */
-+    public MapIterator<K, V> mapIterator() {
-+        return new BidiMapIterator<K, V>(this);
-+    }
-+
-+    public K getKey(Object value) {
-+        return inverseMap.get(value);
-+    }
-+
-+    public K removeValue(Object value) {
-+        K key = null;
-+        if (inverseMap.containsKey(value)) {
-+            key = inverseMap.remove(value);
-+            forwardMap.remove(key);
-+        }
-+        return key;
-+    }
-+
-+    public BidiMap<V, K> inverseBidiMap() {
-+        if (inverseBidiMap == null) {
-+            inverseBidiMap = createBidiMap(inverseMap, forwardMap, this);
-+        }
-+        return inverseBidiMap;
-+    }
-+    
-+    // Map views
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets a keySet view of the map.
-+     * Changes made on the view are reflected in the map.
-+     * The set supports remove and clear but not add.
-+     *
-+     * @return the keySet view
-+     */
-+    public Set<K> keySet() {
-+        if (keySet == null) {
-+            keySet = new KeySet<K, V>(this);
-+        }
-+        return keySet;
-+    }
-+
-+    /**
-+     * Creates a key set iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @param iterator the iterator to decorate
-+     * @return the keySet iterator
-+     */
-+    protected Iterator<K> createKeySetIterator(Iterator<K> iterator) {
-+        return new KeySetIterator<K, V>(iterator, this);
-+    }
-+
-+    /**
-+     * Gets a values view of the map.
-+     * Changes made on the view are reflected in the map.
-+     * The set supports remove and clear but not add.
-+     *
-+     * @return the values view
-+     */
-+    public Set<V> values() {
-+        if (values == null) {
-+            values = new Values<K, V>(this);
-+        }
-+        return values;
-+    }
-+
-+    /**
-+     * Creates a values iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @param iterator the iterator to decorate
-+     * @return the values iterator
-+     */
-+    protected Iterator<V> createValuesIterator(Iterator<V> iterator) {
-+        return new ValuesIterator<K, V>(iterator, this);
-+    }
-+
-+    /**
-+     * Gets an entrySet view of the map.
-+     * Changes made on the set are reflected in the map.
-+     * The set supports remove and clear but not add.
-+     * <p/>
-+     * The Map Entry setValue() method only allow a new value to be set.
-+     * If the value being set is already in the map, an IllegalArgumentException
-+     * is thrown (as setValue cannot change the size of the map).
-+     *
-+     * @return the entrySet view
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        if (entrySet == null) {
-+            entrySet = new EntrySet<K, V>(this);
-+        }
-+        return entrySet;
-+    }
-+
-+    /**
-+     * Creates an entry set iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @param iterator the iterator to decorate
-+     * @return the entrySet iterator
-+     */
-+    protected Iterator<Map.Entry<K, V>> createEntrySetIterator(Iterator<Map.Entry<K, V>> iterator) {
-+        return new EntrySetIterator<K, V>(iterator, this);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inner class View.
-+     */
-+    protected static abstract class View <K,V,E> extends AbstractCollectionDecorator<E> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractDualBidiMap<K, V> parent;
-+
-+        /**
-+         * Constructs a new view of the BidiMap.
-+         *
-+         * @param coll   the collection view being decorated
-+         * @param parent the parent BidiMap
-+         */
-+        protected View(Collection<E> coll, AbstractDualBidiMap<K, V> parent) {
-+            super(coll);
-+            this.parent = parent;
-+        }
-+
-+        public boolean removeAll(Collection<?> coll) {
-+            if (parent.isEmpty() || coll.isEmpty()) {
-+                return false;
-+            }
-+            boolean modified = false;
-+            Iterator it = iterator();
-+            while (it.hasNext()) {
-+                if (coll.contains(it.next())) {
-+                    it.remove();
-+                    modified = true;
-+                }
-+            }
-+            return modified;
-+        }
-+
-+        public boolean retainAll(Collection<?> coll) {
-+            if (parent.isEmpty()) {
-+                return false;
-+            }
-+            if (coll.isEmpty()) {
-+                parent.clear();
-+                return true;
-+            }
-+            boolean modified = false;
-+            Iterator it = iterator();
-+            while (it.hasNext()) {
-+                if (coll.contains(it.next()) == false) {
-+                    it.remove();
-+                    modified = true;
-+                }
-+            }
-+            return modified;
-+        }
-+
-+        public void clear() {
-+            parent.clear();
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inner class KeySet.
-+     */
-+    protected static class KeySet <K,V> extends View<K, V, K> implements Set<K> {
-+
-+        /**
-+         * Constructs a new view of the BidiMap.
-+         *
-+         * @param parent the parent BidiMap
-+         */
-+        protected KeySet(AbstractDualBidiMap<K, V> parent) {
-+            super(parent.forwardMap.keySet(), parent);
-+        }
-+
-+        public Iterator<K> iterator() {
-+            return parent.createKeySetIterator(super.iterator());
-+        }
-+
-+        public boolean contains(Object key) {
-+            return parent.forwardMap.containsKey(key);
-+        }
-+
-+        public boolean remove(Object key) {
-+            if (parent.forwardMap.containsKey(key)) {
-+                Object value = parent.forwardMap.remove(key);
-+                parent.inverseMap.remove(value);
-+                return true;
-+            }
-+            return false;
-+        }
-+    }
-+
-+    /**
-+     * Inner class KeySetIterator.
-+     */
-+    protected static class KeySetIterator <K,V> extends AbstractIteratorDecorator<K> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractDualBidiMap<K, V> parent;
-+        /**
-+         * The last returned key
-+         */
-+        protected K lastKey = null;
-+        /**
-+         * Whether remove is allowed at present
-+         */
-+        protected boolean canRemove = false;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param iterator the iterator to decorate
-+         * @param parent   the parent map
-+         */
-+        protected KeySetIterator(Iterator<K> iterator, AbstractDualBidiMap<K, V> parent) {
-+            super(iterator);
-+            this.parent = parent;
-+        }
-+
-+        public K next() {
-+            lastKey = super.next();
-+            canRemove = true;
-+            return lastKey;
-+        }
-+
-+        public void remove() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException("Iterator remove() can only be called once after next()");
-+            }
-+            Object value = parent.forwardMap.get(lastKey);
-+            super.remove();
-+            parent.inverseMap.remove(value);
-+            lastKey = null;
-+            canRemove = false;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inner class Values.
-+     */
-+    protected static class Values <K,V> extends View<K, V, V> implements Set<V> {
-+
-+        /**
-+         * Constructs a new view of the BidiMap.
-+         *
-+         * @param parent the parent BidiMap
-+         */
-+        protected Values(AbstractDualBidiMap<K, V> parent) {
-+            super(parent.forwardMap.values(), parent);
-+        }
-+
-+        public Iterator<V> iterator() {
-+            return parent.createValuesIterator(super.iterator());
-+        }
-+
-+        public boolean contains(Object value) {
-+            return parent.inverseMap.containsKey(value);
-+        }
-+
-+        public boolean remove(Object value) {
-+            if (parent.inverseMap.containsKey(value)) {
-+                Object key = parent.inverseMap.remove(value);
-+                parent.forwardMap.remove(key);
-+                return true;
-+            }
-+            return false;
-+        }
-+    }
-+
-+    /**
-+     * Inner class ValuesIterator.
-+     */
-+    protected static class ValuesIterator <K,V> extends AbstractIteratorDecorator<V> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractDualBidiMap<K, V> parent;
-+        /**
-+         * The last returned value
-+         */
-+        protected V lastValue = null;
-+        /**
-+         * Whether remove is allowed at present
-+         */
-+        protected boolean canRemove = false;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param iterator the iterator to decorate
-+         * @param parent   the parent map
-+         */
-+        protected ValuesIterator(Iterator<V> iterator, AbstractDualBidiMap<K, V> parent) {
-+            super(iterator);
-+            this.parent = parent;
-+        }
-+
-+        public V next() {
-+            lastValue = super.next();
-+            canRemove = true;
-+            return lastValue;
-+        }
-+
-+        public void remove() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException("Iterator remove() can only be called once after next()");
-+            }
-+            super.remove(); // removes from forwardMap
-+            parent.inverseMap.remove(lastValue);
-+            lastValue = null;
-+            canRemove = false;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inner class EntrySet.
-+     */
-+    protected static class EntrySet <K,V> extends View<K, V, Map.Entry<K, V>> implements Set<Map.Entry<K, V>> {
-+
-+        /**
-+         * Constructs a new view of the BidiMap.
-+         *
-+         * @param parent the parent BidiMap
-+         */
-+        protected EntrySet(AbstractDualBidiMap<K, V> parent) {
-+            super(parent.forwardMap.entrySet(), parent);
-+        }
-+
-+        public Iterator<Map.Entry<K, V>> iterator() {
-+            return parent.createEntrySetIterator(super.iterator());
-+        }
-+
-+        public boolean remove(Object obj) {
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry entry = (Map.Entry) obj;
-+            Object key = entry.getKey();
-+            if (parent.containsKey(key)) {
-+                Object value = parent.forwardMap.get(key);
-+                if (value == null ? entry.getValue() == null : value.equals(entry.getValue())) {
-+                    parent.forwardMap.remove(key);
-+                    parent.inverseMap.remove(value);
-+                    return true;
-+                }
-+            }
-+            return false;
-+        }
-+    }
-+
-+    /**
-+     * Inner class EntrySetIterator.
-+     */
-+    protected static class EntrySetIterator <K,V> extends AbstractIteratorDecorator<Map.Entry<K, V>> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractDualBidiMap<K, V> parent;
-+        /**
-+         * The last returned entry
-+         */
-+        protected Map.Entry<K, V> last = null;
-+        /**
-+         * Whether remove is allowed at present
-+         */
-+        protected boolean canRemove = false;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param iterator the iterator to decorate
-+         * @param parent   the parent map
-+         */
-+        protected EntrySetIterator(Iterator<Map.Entry<K, V>> iterator, AbstractDualBidiMap<K, V> parent) {
-+            super(iterator);
-+            this.parent = parent;
-+        }
-+
-+        public Map.Entry<K, V> next() {
-+            last = new MapEntry<K, V>(super.next(), parent);
-+            canRemove = true;
-+            return last;
-+        }
-+
-+        public void remove() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException("Iterator remove() can only be called once after next()");
-+            }
-+            // store value as remove may change the entry in the decorator (eg.TreeMap)
-+            Object value = last.getValue();
-+            super.remove();
-+            parent.inverseMap.remove(value);
-+            last = null;
-+            canRemove = false;
-+        }
-+    }
-+
-+    /**
-+     * Inner class MapEntry.
-+     */
-+    protected static class MapEntry <K,V> extends AbstractMapEntryDecorator<K, V> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractDualBidiMap<K, V> parent;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param entry  the entry to decorate
-+         * @param parent the parent map
-+         */
-+        protected MapEntry(Map.Entry<K, V> entry, AbstractDualBidiMap<K, V> parent) {
-+            super(entry);
-+            this.parent = parent;
-+        }
-+
-+        public V setValue(V value) {
-+            K key = MapEntry.this.getKey();
-+            if (parent.inverseMap.containsKey(value) && parent.inverseMap.get(value) != key) {
-+                throw new IllegalArgumentException("Cannot use setValue() when the object being set is already in the map");
-+            }
-+            parent.put(key, value);
-+            final V oldValue = super.setValue(value);
-+            return oldValue;
-+        }
-+    }
-+
-+    /**
-+     * Inner class MapIterator.
-+     */
-+    protected static class BidiMapIterator <K,V> implements MapIterator<K, V>, ResettableIterator<K> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractDualBidiMap<K, V> parent;
-+        /**
-+         * The iterator being wrapped
-+         */
-+        protected Iterator<Map.Entry<K, V>> iterator;
-+        /**
-+         * The last returned entry
-+         */
-+        protected Map.Entry<K, V> last = null;
-+        /**
-+         * Whether remove is allowed at present
-+         */
-+        protected boolean canRemove = false;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param parent the parent map
-+         */
-+        protected BidiMapIterator(AbstractDualBidiMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+            this.iterator = parent.forwardMap.entrySet().iterator();
-+        }
-+
-+        public boolean hasNext() {
-+            return iterator.hasNext();
-+        }
-+
-+        public K next() {
-+            last = iterator.next();
-+            canRemove = true;
-+            return last.getKey();
-+        }
-+
-+        public void remove() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException("Iterator remove() can only be called once after next()");
-+            }
-+            // store value as remove may change the entry in the decorator (eg.TreeMap)
-+            V value = last.getValue();
-+            iterator.remove();
-+            parent.inverseMap.remove(value);
-+            last = null;
-+            canRemove = false;
-+        }
-+
-+        public K getKey() {
-+            if (last == null) {
-+                throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
-+            }
-+            return last.getKey();
-+        }
-+
-+        public V getValue() {
-+            if (last == null) {
-+                throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
-+            }
-+            return last.getValue();
-+        }
-+
-+        public V setValue(V value) {
-+            if (last == null) {
-+                throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
-+            }
-+            if (parent.inverseMap.containsKey(value) && parent.inverseMap.get(value) != last.getKey()) {
-+                throw new IllegalArgumentException("Cannot use setValue() when the object being set is already in the map");
-+            }
-+            return parent.put(last.getKey(), value);
-+        }
-+
-+        public void reset() {
-+            iterator = parent.forwardMap.entrySet().iterator();
-+            last = null;
-+            canRemove = false;
-+        }
-+
-+        public String toString() {
-+            if (last != null) {
-+                return "MapIterator[" + getKey() + "=" + getValue() + "]";
-+            } else {
-+                return "MapIterator[]";
-+            }
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/AbstractOrderedBidiMapDecorator.java
-@@ -0,0 +1,84 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.OrderedBidiMap;
-+import org.apache.commons.collections15.OrderedMapIterator;
-+
-+/**
-+ * Provides a base decorator that enables additional functionality to be added
-+ * to an OrderedBidiMap via decoration.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated map.
-+ * <p/>
-+ * This implementation does not perform any special processing with the map views.
-+ * Instead it simply returns the inverse from the wrapped map. This may be
-+ * undesirable, for example if you are trying to write a validating implementation
-+ * it would provide a loophole around the validation.
-+ * But, you might want that loophole, so this class is kept simple.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractOrderedBidiMapDecorator <K,V> extends AbstractBidiMapDecorator<K, V> implements OrderedBidiMap<K, V> {
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    protected AbstractOrderedBidiMapDecorator(OrderedBidiMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected OrderedBidiMap<K, V> getOrderedBidiMap() {
-+        return (OrderedBidiMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        return getOrderedBidiMap().orderedMapIterator();
-+    }
-+
-+    public K firstKey() {
-+        return getOrderedBidiMap().firstKey();
-+    }
-+
-+    public K lastKey() {
-+        return getOrderedBidiMap().lastKey();
-+    }
-+
-+    public K nextKey(K key) {
-+        return getOrderedBidiMap().nextKey(key);
-+    }
-+
-+    public K previousKey(K key) {
-+        return getOrderedBidiMap().previousKey(key);
-+    }
-+
-+    public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
-+        return getOrderedBidiMap().inverseOrderedBidiMap();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/AbstractSortedBidiMapDecorator.java
-@@ -0,0 +1,82 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.SortedBidiMap;
-+
-+import java.util.Comparator;
-+import java.util.SortedMap;
-+
-+/**
-+ * Provides a base decorator that enables additional functionality to be added
-+ * to a SortedBidiMap via decoration.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated map.
-+ * <p/>
-+ * This implementation does not perform any special processing with the map views.
-+ * Instead it simply returns the inverse from the wrapped map. This may be
-+ * undesirable, for example if you are trying to write a validating implementation
-+ * it would provide a loophole around the validation.
-+ * But, you might want that loophole, so this class is kept simple.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractSortedBidiMapDecorator <K,V> extends AbstractOrderedBidiMapDecorator<K, V> implements SortedBidiMap<K, V> {
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractSortedBidiMapDecorator(SortedBidiMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected SortedBidiMap<K, V> getSortedBidiMap() {
-+        return (SortedBidiMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedBidiMap<V, K> inverseSortedBidiMap() {
-+        return getSortedBidiMap().inverseSortedBidiMap();
-+    }
-+
-+    public Comparator<? super K> comparator() {
-+        return getSortedBidiMap().comparator();
-+    }
-+
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        return getSortedBidiMap().subMap(fromKey, toKey);
-+    }
-+
-+    public SortedMap<K, V> headMap(K toKey) {
-+        return getSortedBidiMap().headMap(toKey);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        return getSortedBidiMap().tailMap(fromKey);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/DualHashBidiMap.java
-@@ -0,0 +1,107 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.BidiMap;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.HashMap;
-+import java.util.Map;
-+
-+/**
-+ * Implementation of <code>BidiMap</code> that uses two <code>HashMap</code> instances.
-+ * <p/>
-+ * Two <code>HashMap</code> instances are used in this class.
-+ * This provides fast lookups at the expense of storing two sets of map entries.
-+ * Commons Collections would welcome the addition of a direct hash-based
-+ * implementation of the <code>BidiMap</code> interface.
-+ * <p/>
-+ * NOTE: From Commons Collections 3.1, all subclasses will use <code>HashMap</code>
-+ * and the flawed <code>createMap</code> method is ignored.
-+ *
-+ * @author Matthew Hawthorne
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Id: DualHashBidiMap.java,v 1.1 2005/10/11 17:05:19 pents90 Exp $
-+ * @since Commons Collections 3.0
-+ */
-+public class DualHashBidiMap <K,V> extends AbstractDualBidiMap<K, V> implements Serializable {
-+
-+    /**
-+     * Ensure serialization compatibility
-+     */
-+    private static final long serialVersionUID = 721969328361808L;
-+
-+    /**
-+     * Creates an empty <code>HashBidiMap</code>.
-+     */
-+    public DualHashBidiMap() {
-+        super(new HashMap<K, V>(), new HashMap<V, K>());
-+    }
-+
-+    /**
-+     * Constructs a <code>HashBidiMap</code> and copies the mappings from
-+     * specified <code>Map</code>.
-+     *
-+     * @param map the map whose mappings are to be placed in this map
-+     */
-+    public DualHashBidiMap(Map<? extends K, ? extends V> map) {
-+        super(new HashMap<K, V>(), new HashMap<V, K>());
-+        putAll(map);
-+    }
-+
-+    /**
-+     * Constructs a <code>HashBidiMap</code> that decorates the specified maps.
-+     *
-+     * @param normalMap      the normal direction map
-+     * @param reverseMap     the reverse direction map
-+     * @param inverseBidiMap the inverse BidiMap
-+     */
-+    protected DualHashBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseBidiMap) {
-+        super(normalMap, reverseMap, inverseBidiMap);
-+    }
-+
-+    /**
-+     * Creates a new instance of this object.
-+     *
-+     * @param normalMap      the normal direction map
-+     * @param reverseMap     the reverse direction map
-+     * @param inverseBidiMap the inverse BidiMap
-+     * @return new bidi map
-+     */
-+    protected <K,V> BidiMap<K, V> createBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseBidiMap) {
-+        return new DualHashBidiMap<K, V>(normalMap, reverseMap, inverseBidiMap);
-+    }
-+
-+    // Serialization
-+    //-----------------------------------------------------------------------
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(forwardMap);
-+    }
-+
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        forwardMap = new HashMap<K, V>();
-+        inverseMap = new HashMap<V, K>();
-+        Map<K, V> map = (Map<K, V>) in.readObject();
-+        putAll(map);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/DualTreeBidiMap.java
-@@ -0,0 +1,353 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.*;
-+import org.apache.commons.collections15.map.AbstractSortedMapDecorator;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * Implementation of <code>BidiMap</code> that uses two <code>TreeMap</code> instances.
-+ * <p/>
-+ * The setValue() method on iterators will succeed only if the new value being set is
-+ * not already in the bidimap.
-+ * <p/>
-+ * When considering whether to use this class, the {@link TreeBidiMap} class should
-+ * also be considered. It implements the interface using a dedicated design, and does
-+ * not store each object twice, which can save on memory use.
-+ * <p/>
-+ * NOTE: From Commons Collections 3.1, all subclasses will use <code>TreeMap</code>
-+ * and the flawed <code>createMap</code> method is ignored.
-+ *
-+ * @author Matthew Hawthorne
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Id: DualTreeBidiMap.java,v 1.1 2005/10/11 17:05:19 pents90 Exp $
-+ * @since Commons Collections 3.0
-+ */
-+public class DualTreeBidiMap <K,V> extends AbstractDualBidiMap<K, V> implements SortedBidiMap<K, V>, Serializable {
-+
-+    /**
-+     * Ensure serialization compatibility
-+     */
-+    private static final long serialVersionUID = 721969328361809L;
-+    /**
-+     * The comparator to use
-+     */
-+    protected final Comparator<? super K> comparator;
-+
-+    /**
-+     * Creates an empty <code>DualTreeBidiMap</code>
-+     */
-+    public DualTreeBidiMap() {
-+        super(new TreeMap<K, V>(), new TreeMap<V, K>());
-+        this.comparator = null;
-+    }
-+
-+    public static <E> DualTreeBidiMap<E, E> createTwoWayBidiMap(Comparator<? super E> comparator) {
-+        return new DualTreeBidiMap<E, E>(comparator, comparator);
-+    }
-+
-+    /**
-+     * Constructs a <code>DualTreeBidiMap</code> and copies the mappings from
-+     * specified <code>Map</code>.
-+     *
-+     * @param map the map whose mappings are to be placed in this map
-+     */
-+    public DualTreeBidiMap(Map<? extends K, ? extends V> map) {
-+        super(new TreeMap<K, V>(), new TreeMap<V, K>());
-+        putAll(map);
-+        this.comparator = null;
-+    }
-+
-+    /**
-+     * Constructs a <code>DualTreeBidiMap</code> using the specified Comparators.
-+     *
-+     * @param comparator the Comparator
-+     */
-+    public DualTreeBidiMap(Comparator<? super K> comparator, Comparator<? super V> inverseComparator) {
-+        super(new TreeMap<K, V>(comparator), new TreeMap<V, K>(inverseComparator));
-+        this.comparator = comparator;
-+    }
-+
-+    /**
-+     * Constructs a <code>DualTreeBidiMap</code> that decorates the specified maps.
-+     *
-+     * @param normalMap      the normal direction map
-+     * @param reverseMap     the reverse direction map
-+     * @param inverseBidiMap the inverse BidiMap
-+     */
-+    protected DualTreeBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseBidiMap) {
-+        super(normalMap, reverseMap, inverseBidiMap);
-+        this.comparator = ((SortedMap<K, V>) normalMap).comparator();
-+    }
-+
-+    /**
-+     * Creates a new instance of this object.
-+     *
-+     * @param normalMap  the normal direction map
-+     * @param reverseMap the reverse direction map
-+     * @param inverseMap the inverse BidiMap
-+     * @return new bidi map
-+     */
-+    protected <K,V> BidiMap<K, V> createBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, BidiMap<V, K> inverseMap) {
-+        return new DualTreeBidiMap<K, V>(normalMap, reverseMap, inverseMap);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Comparator<? super K> comparator() {
-+        return ((SortedMap<K, V>) forwardMap).comparator();
-+    }
-+
-+    public K firstKey() {
-+        return ((SortedMap<K, V>) forwardMap).firstKey();
-+    }
-+
-+    public K lastKey() {
-+        return ((SortedMap<K, V>) forwardMap).lastKey();
-+    }
-+
-+    public K nextKey(K key) {
-+        if (isEmpty()) {
-+            return null;
-+        }
-+        if (forwardMap instanceof OrderedMap) {
-+            return ((OrderedMap<K, V>) forwardMap).nextKey(key);
-+        }
-+        SortedMap sm = (SortedMap) forwardMap;
-+        Iterator<K> it = sm.tailMap(key).keySet().iterator();
-+        it.next();
-+        if (it.hasNext()) {
-+            return it.next();
-+        }
-+        return null;
-+    }
-+
-+    public K previousKey(K key) {
-+        if (isEmpty()) {
-+            return null;
-+        }
-+        if (forwardMap instanceof OrderedMap) {
-+            return ((OrderedMap<K, V>) forwardMap).previousKey(key);
-+        }
-+        SortedMap<K, V> sm = (SortedMap<K, V>) forwardMap;
-+        SortedMap<K, V> hm = sm.headMap(key);
-+        if (hm.isEmpty()) {
-+            return null;
-+        }
-+        return hm.lastKey();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Obtains an ordered map iterator.
-+     * <p/>
-+     * This implementation copies the elements to an ArrayList in order to
-+     * provide the forward/backward behaviour.
-+     *
-+     * @return a new ordered map iterator
-+     */
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        return new BidiOrderedMapIterator<K, V>(this);
-+    }
-+
-+    public SortedBidiMap<V, K> inverseSortedBidiMap() {
-+        return (SortedBidiMap<V, K>) inverseBidiMap();
-+    }
-+
-+    public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
-+        return (OrderedBidiMap<V, K>) inverseBidiMap();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedMap<K, V> headMap(K toKey) {
-+        SortedMap<K, V> sub = ((SortedMap<K, V>) forwardMap).headMap(toKey);
-+        return new ViewMap(this, sub);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        SortedMap<K, V> sub = ((SortedMap<K, V>) forwardMap).tailMap(fromKey);
-+        return new ViewMap<K, V>(this, sub);
-+    }
-+
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        SortedMap<K, V> sub = ((SortedMap<K, V>) forwardMap).subMap(fromKey, toKey);
-+        return new ViewMap<K, V>(this, sub);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Internal sorted map view.
-+     */
-+    protected static class ViewMap <K,V> extends AbstractSortedMapDecorator<K, V> {
-+        /**
-+         * The parent bidi map.
-+         */
-+        final DualTreeBidiMap<K, V> bidi;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param bidi the parent bidi map
-+         * @param sm   the subMap sorted map
-+         */
-+        protected ViewMap(DualTreeBidiMap<K, V> bidi, SortedMap<K, V> sm) {
-+            // the implementation is not great here...
-+            // use the forwardMap as the filtered map, but inverseMap as the full map
-+            // this forces containsValue and clear to be overridden
-+            super((SortedMap) bidi.createBidiMap(sm, bidi.inverseMap, bidi.inverseBidiMap));
-+            this.bidi = (DualTreeBidiMap) map;
-+        }
-+
-+        public boolean containsValue(Object value) {
-+            // override as default implementation jumps to [1]
-+            return bidi.forwardMap.containsValue(value);
-+        }
-+
-+        public void clear() {
-+            // override as default implementation jumps to [1]
-+            for (Iterator it = keySet().iterator(); it.hasNext();) {
-+                it.next();
-+                it.remove();
-+            }
-+        }
-+
-+        public SortedMap<K, V> headMap(K toKey) {
-+            return new ViewMap<K, V>(bidi, super.headMap(toKey));
-+        }
-+
-+        public SortedMap<K, V> tailMap(K fromKey) {
-+            return new ViewMap<K, V>(bidi, super.tailMap(fromKey));
-+        }
-+
-+        public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+            return new ViewMap<K, V>(bidi, super.subMap(fromKey, toKey));
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inner class MapIterator.
-+     */
-+    protected static class BidiOrderedMapIterator <K,V> implements OrderedMapIterator<K, V>, ResettableIterator<K> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractDualBidiMap<K, V> parent;
-+        /**
-+         * The iterator being decorated
-+         */
-+        protected ListIterator<Map.Entry<K, V>> iterator;
-+        /**
-+         * The last returned entry
-+         */
-+        private Map.Entry<K, V> last = null;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param parent the parent map
-+         */
-+        protected BidiOrderedMapIterator(AbstractDualBidiMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+            iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator();
-+        }
-+
-+        public boolean hasNext() {
-+            return iterator.hasNext();
-+        }
-+
-+        public K next() {
-+            last = iterator.next();
-+            return last.getKey();
-+        }
-+
-+        public boolean hasPrevious() {
-+            return iterator.hasPrevious();
-+        }
-+
-+        public K previous() {
-+            last = iterator.previous();
-+            return last.getKey();
-+        }
-+
-+        public void remove() {
-+            iterator.remove();
-+            parent.remove(last.getKey());
-+            last = null;
-+        }
-+
-+        public K getKey() {
-+            if (last == null) {
-+                throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
-+            }
-+            return last.getKey();
-+        }
-+
-+        public V getValue() {
-+            if (last == null) {
-+                throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
-+            }
-+            return last.getValue();
-+        }
-+
-+        public V setValue(V value) {
-+            if (last == null) {
-+                throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
-+            }
-+            if (parent.inverseMap.containsKey(value) && parent.inverseMap.get(value) != last.getKey()) {
-+                throw new IllegalArgumentException("Cannot use setValue() when the object being set is already in the map");
-+            }
-+            return parent.put(last.getKey(), value);
-+        }
-+
-+        public void reset() {
-+            iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator();
-+            last = null;
-+        }
-+
-+        public String toString() {
-+            if (last != null) {
-+                return "MapIterator[" + getKey() + "=" + getValue() + "]";
-+            } else {
-+                return "MapIterator[]";
-+            }
-+        }
-+    }
-+
-+    // Serialization
-+    //-----------------------------------------------------------------------
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(forwardMap);
-+    }
-+
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        forwardMap = new TreeMap<K, V>(comparator);
-+        inverseMap = new TreeMap<V, K>();
-+        Map<K, V> map = (Map<K, V>) in.readObject();
-+        putAll(map);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/TreeBidiMap.java
-@@ -0,0 +1,2144 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.*;
-+import org.apache.commons.collections15.iterators.EmptyOrderedMapIterator;
-+import org.apache.commons.collections15.keyvalue.UnmodifiableMapEntry;
-+
-+import java.util.*;
-+
-+/**
-+ * Red-Black tree-based implementation of BidiMap where all objects added
-+ * implement the <code>Comparable</code> interface.
-+ * <p/>
-+ * This class guarantees that the map will be in both ascending key order
-+ * and ascending value order, sorted according to the natural order for
-+ * the key's and value's classes.
-+ * <p/>
-+ * This Map is intended for applications that need to be able to look
-+ * up a key-value pairing by either key or value, and need to do so
-+ * with equal efficiency.
-+ * <p/>
-+ * While that goal could be accomplished by taking a pair of TreeMaps
-+ * and redirecting requests to the appropriate TreeMap (e.g.,
-+ * containsKey would be directed to the TreeMap that maps values to
-+ * keys, containsValue would be directed to the TreeMap that maps keys
-+ * to values), there are problems with that implementation.
-+ * If the data contained in the TreeMaps is large, the cost of redundant
-+ * storage becomes significant. The {@link DualTreeBidiMap} and
-+ * {@link DualHashBidiMap} implementations use this approach.
-+ * <p/>
-+ * This solution keeps minimizes the data storage by holding data only once.
-+ * The red-black algorithm is based on java util TreeMap, but has been modified
-+ * to simultaneously map a tree node by key and by value. This doubles the
-+ * cost of put operations (but so does using two TreeMaps), and nearly doubles
-+ * the cost of remove operations (there is a savings in that the lookup of the
-+ * node to be removed only has to be performed once). And since only one node
-+ * contains the key and value, storage is significantly less than that
-+ * required by two TreeMaps.
-+ * <p/>
-+ * The Map.Entry instances returned by the appropriate methods will
-+ * not allow setValue() and will throw an
-+ * UnsupportedOperationException on attempts to call that method.
-+ *
-+ * @author Marc Johnson
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0 (previously DoubleOrderedMap v2.0)
-+ */
-+public class TreeBidiMap <K extends Comparable,V extends Comparable> implements OrderedBidiMap<K, V> {
-+
-+    private static final int KEY = 0;
-+    private static final int VALUE = 1;
-+    private static final int MAPENTRY = 2;
-+    private static final int INVERSEMAPENTRY = 3;
-+    private static final int SUM_OF_INDICES = KEY + VALUE;
-+    private static final int FIRST_INDEX = 0;
-+    private static final int NUMBER_OF_INDICES = 2;
-+    private static final String[] dataName = new String[]{"key", "value"};
-+
-+    private Node<K, V>[] rootNode = new Node[2];
-+    private int nodeCount = 0;
-+    private int modifications = 0;
-+    private Set<K> keySet;
-+    private Set<V> valuesSet;
-+    private Set entrySet;
-+    private TreeBidiMap.Inverse<K, V> inverse = null;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new empty TreeBidiMap.
-+     */
-+    public TreeBidiMap() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new TreeBidiMap by copying an existing Map.
-+     *
-+     * @param map the map to copy
-+     * @throws ClassCastException   if the keys/values in the map are
-+     *                              not Comparable or are not mutually comparable
-+     * @throws NullPointerException if any key or value in the map is null
-+     */
-+    public TreeBidiMap(final Map map) {
-+        super();
-+        putAll(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the number of key-value mappings in this map.
-+     *
-+     * @return the number of key-value mappings in this map
-+     */
-+    public int size() {
-+        return nodeCount;
-+    }
-+
-+    /**
-+     * Checks whether the map is empty or not.
-+     *
-+     * @return true if the map is empty
-+     */
-+    public boolean isEmpty() {
-+        return (nodeCount == 0);
-+    }
-+
-+    /**
-+     * Checks whether this map contains the a mapping for the specified key.
-+     * <p/>
-+     * The key must implement <code>Comparable</code>.
-+     *
-+     * @param key key whose presence in this map is to be tested
-+     * @return true if this map contains a mapping for the specified key
-+     * @throws ClassCastException   if the key is of an inappropriate type
-+     * @throws NullPointerException if the key is null
-+     */
-+    public boolean containsKey(final Object key) {
-+        checkKey(key);
-+        return (lookup((Comparable) key, KEY) != null);
-+    }
-+
-+    /**
-+     * Checks whether this map contains the a mapping for the specified value.
-+     * <p/>
-+     * The value must implement <code>Comparable</code>.
-+     *
-+     * @param value value whose presence in this map is to be tested
-+     * @return true if this map contains a mapping for the specified value
-+     * @throws ClassCastException   if the value is of an inappropriate type
-+     * @throws NullPointerException if the value is null
-+     */
-+    public boolean containsValue(final Object value) {
-+        checkValue(value);
-+        return (lookup((Comparable) value, VALUE) != null);
-+    }
-+
-+    /**
-+     * Gets the value to which this map maps the specified key.
-+     * Returns null if the map contains no mapping for this key.
-+     * <p/>
-+     * The key must implement <code>Comparable</code>.
-+     *
-+     * @param key key whose associated value is to be returned
-+     * @return the value to which this map maps the specified key,
-+     *         or null if the map contains no mapping for this key
-+     * @throws ClassCastException   if the key is of an inappropriate type
-+     * @throws NullPointerException if the key is null
-+     */
-+    public V get(final Object key) {
-+        return doGetValue(key);
-+    }
-+
-+    /**
-+     * Puts the key-value pair into the map, replacing any previous pair.
-+     * <p/>
-+     * When adding a key-value pair, the value may already exist in the map
-+     * against a different key. That mapping is removed, to ensure that the
-+     * value only occurs once in the inverse map.
-+     * <pre>
-+     *  BidiMap map1 = new TreeBidiMap();
-+     *  map.put("A","B");  // contains A mapped to B, as per Map
-+     *  map.put("A","C");  // contains A mapped to C, as per Map
-+     * <p/>
-+     *  BidiMap map2 = new TreeBidiMap();
-+     *  map.put("A","B");  // contains A mapped to B, as per Map
-+     *  map.put("C","B");  // contains C mapped to B, key A is removed
-+     * </pre>
-+     * <p/>
-+     * Both key and value must implement <code>Comparable</code>.
-+     *
-+     * @param key   key with which the specified value is to be  associated
-+     * @param value value to be associated with the specified key
-+     * @return the previous value for the key
-+     * @throws ClassCastException   if the key is of an inappropriate type
-+     * @throws NullPointerException if the key is null
-+     */
-+    public V put(final K key, final V value) {
-+        return doPutByKey(key, value);
-+    }
-+
-+    /**
-+     * Puts all the mappings from the specified map into this map.
-+     * <p/>
-+     * All keys and values must implement <code>Comparable</code>.
-+     *
-+     * @param map the map to copy from
-+     */
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        Iterator it = map.entrySet().iterator();
-+        while (it.hasNext()) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            put((K) entry.getKey(), (V) entry.getValue());
-+        }
-+    }
-+
-+    /**
-+     * Removes the mapping for this key from this map if present.
-+     * <p/>
-+     * The key must implement <code>Comparable</code>.
-+     *
-+     * @param key key whose mapping is to be removed from the map.
-+     * @return previous value associated with specified key,
-+     *         or null if there was no mapping for key.
-+     * @throws ClassCastException   if the key is of an inappropriate type
-+     * @throws NullPointerException if the key is null
-+     */
-+    public V remove(final Object key) {
-+        return doRemoveByKey((K) key);
-+    }
-+
-+    /**
-+     * Removes all mappings from this map.
-+     */
-+    public void clear() {
-+        modify();
-+
-+        nodeCount = 0;
-+        rootNode[KEY] = null;
-+        rootNode[VALUE] = null;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the key to which this map maps the specified value.
-+     * Returns null if the map contains no mapping for this value.
-+     * <p/>
-+     * The value must implement <code>Comparable</code>.
-+     *
-+     * @param value value whose associated key is to be returned.
-+     * @return the key to which this map maps the specified value,
-+     *         or null if the map contains no mapping for this value.
-+     * @throws ClassCastException   if the value is of an inappropriate type
-+     * @throws NullPointerException if the value is null
-+     */
-+    public K getKey(final Object value) {
-+        return doGetKey((Comparable) value);
-+    }
-+
-+    /**
-+     * Removes the mapping for this value from this map if present.
-+     * <p/>
-+     * The value must implement <code>Comparable</code>.
-+     *
-+     * @param value value whose mapping is to be removed from the map
-+     * @return previous key associated with specified value,
-+     *         or null if there was no mapping for value.
-+     * @throws ClassCastException   if the value is of an inappropriate type
-+     * @throws NullPointerException if the value is null
-+     */
-+    public K removeValue(final Object value) {
-+        return doRemoveByValue((Comparable) value);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the first (lowest) key currently in this map.
-+     *
-+     * @return the first (lowest) key currently in this sorted map
-+     * @throws NoSuchElementException if this map is empty
-+     */
-+    public K firstKey() {
-+        if (nodeCount == 0) {
-+            throw new NoSuchElementException("Map is empty");
-+        }
-+        return leastNode(rootNode[KEY], KEY).getKey();
-+    }
-+
-+    /**
-+     * Gets the last (highest) key currently in this map.
-+     *
-+     * @return the last (highest) key currently in this sorted map
-+     * @throws NoSuchElementException if this map is empty
-+     */
-+    public K lastKey() {
-+        if (nodeCount == 0) {
-+            throw new NoSuchElementException("Map is empty");
-+        }
-+        return greatestNode(rootNode[KEY], KEY).getKey();
-+    }
-+
-+    /**
-+     * Gets the next key after the one specified.
-+     * <p/>
-+     * The key must implement <code>Comparable</code>.
-+     *
-+     * @param key the key to search for next from
-+     * @return the next key, null if no match or at end
-+     */
-+    public K nextKey(K key) {
-+        checkKey(key);
-+        Node<K, V> node = nextGreater(lookup(key, KEY), KEY);
-+        return (node == null ? null : node.getKey());
-+    }
-+
-+    /**
-+     * Gets the previous key before the one specified.
-+     * <p/>
-+     * The key must implement <code>Comparable</code>.
-+     *
-+     * @param key the key to search for previous from
-+     * @return the previous key, null if no match or at start
-+     */
-+    public K previousKey(K key) {
-+        checkKey(key);
-+        Node<K, V> node = nextSmaller(lookup((Comparable) key, KEY), KEY);
-+        return (node == null ? null : node.getKey());
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a set view of the keys contained in this map in key order.
-+     * <p/>
-+     * The set is backed by the map, so changes to the map are reflected in
-+     * the set, and vice-versa. If the map is modified while an iteration over
-+     * the set is in progress, the results of the iteration are undefined.
-+     * <p/>
-+     * The set supports element removal, which removes the corresponding mapping
-+     * from the map. It does not support the add or addAll operations.
-+     *
-+     * @return a set view of the keys contained in this map.
-+     */
-+    public Set<K> keySet() {
-+        if (keySet == null) {
-+            keySet = new View(this, KEY, KEY);
-+        }
-+        return keySet;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a set view of the values contained in this map in key order.
-+     * The returned object can be cast to a Set.
-+     * <p/>
-+     * The set is backed by the map, so changes to the map are reflected in
-+     * the set, and vice-versa. If the map is modified while an iteration over
-+     * the set is in progress, the results of the iteration are undefined.
-+     * <p/>
-+     * The set supports element removal, which removes the corresponding mapping
-+     * from the map. It does not support the add or addAll operations.
-+     *
-+     * @return a set view of the values contained in this map.
-+     */
-+    public Set<V> values() {
-+        if (valuesSet == null) {
-+            valuesSet = new View(this, KEY, VALUE);
-+        }
-+        return valuesSet;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a set view of the entries contained in this map in key order.
-+     * For simple iteration through the map, the MapIterator is quicker.
-+     * <p/>
-+     * The set is backed by the map, so changes to the map are reflected in
-+     * the set, and vice-versa. If the map is modified while an iteration over
-+     * the set is in progress, the results of the iteration are undefined.
-+     * <p/>
-+     * The set supports element removal, which removes the corresponding mapping
-+     * from the map. It does not support the add or addAll operations.
-+     * The returned MapEntry objects do not support setValue.
-+     *
-+     * @return a set view of the values contained in this map.
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        if (entrySet == null) {
-+            return new EntryView(this, KEY, MAPENTRY);
-+        }
-+        return entrySet;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator over the map entries.
-+     * <p/>
-+     * For this map, this iterator is the fastest way to iterate over the entries.
-+     *
-+     * @return an iterator
-+     */
-+    public MapIterator<K, V> mapIterator() {
-+        if (isEmpty()) {
-+            return EmptyOrderedMapIterator.INSTANCE;
-+        }
-+        return new ViewMapIterator(this, KEY);
-+    }
-+
-+    /**
-+     * Gets an ordered iterator over the map entries.
-+     * <p/>
-+     * This iterator allows both forward and reverse iteration over the entries.
-+     *
-+     * @return an iterator
-+     */
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        if (isEmpty()) {
-+            return EmptyOrderedMapIterator.INSTANCE;
-+        }
-+        return new ViewMapIterator(this, KEY);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the inverse map for comparison.
-+     *
-+     * @return the inverse map
-+     */
-+    public BidiMap<V, K> inverseBidiMap() {
-+        return inverseOrderedBidiMap();
-+    }
-+
-+    /**
-+     * Gets the inverse map for comparison.
-+     *
-+     * @return the inverse map
-+     */
-+    public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
-+        if (inverse == null) {
-+            inverse = new Inverse<K, V>(this);
-+        }
-+        return inverse;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares for equals as per the API.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object obj) {
-+        return this.doEquals(obj, KEY);
-+    }
-+
-+    /**
-+     * Gets the hash code value for this map as per the API.
-+     *
-+     * @return the hash code value for this map
-+     */
-+    public int hashCode() {
-+        return this.doHashCode(KEY);
-+    }
-+
-+    /**
-+     * Returns a string version of this Map in standard format.
-+     *
-+     * @return a standard format string version of the map
-+     */
-+    public String toString() {
-+        return this.doToString(KEY);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+
-+    /**
-+     * Common get logic, used to get by value
-+     *
-+     * @param value the key or value that we're looking for
-+     * @return the key (if the value was mapped) or the value (if the
-+     *         key was mapped); null if we couldn't find the specified
-+     *         object
-+     */
-+    private K doGetKey(final Comparable value) {
-+        checkNonNullComparable(value);
-+        Node<K, V> node = lookup(value, VALUE);
-+        if (node == null) {
-+            return null;
-+        } else {
-+            return node.getKey();
-+        }
-+    }
-+
-+    /**
-+     * Common get logic, used to get by key
-+     *
-+     * @param key the key or value that we're looking for
-+     * @return the key (if the value was mapped) or the value (if the
-+     *         key was mapped); null if we couldn't find the specified
-+     *         object
-+     */
-+    private V doGetValue(final Object key) {
-+        checkNonNullComparable(key);
-+        Node<K, V> node = lookup((Comparable) key, KEY);
-+        if (node == null) {
-+            return null;
-+        } else {
-+            return node.getValue();
-+        }
-+    }
-+
-+    /**
-+     * Common put logic
-+     *
-+     * @param key   the key, always the main map key
-+     * @param value the value, always the main map value
-+     * @return the previously mapped value
-+     */
-+    private V doPutByKey(final K key, final V value) {
-+        checkKeyAndValue(key, value);
-+        
-+        // store previous and remove previous mappings
-+        V prev = doGetValue(key);
-+
-+        doPut(key, value);
-+        return prev;
-+    }
-+
-+    /**
-+     * Common put logic
-+     *
-+     * @param key   the key, always the main map key
-+     * @param value the value, always the main map value
-+     * @return the previously mapped value
-+     */
-+    private K doPutByValue(final K key, final V value) {
-+        checkKeyAndValue(key, value);
-+
-+        // store previous and remove previous mappings
-+        K prev = doGetKey(value);
-+
-+        doPut(key, value);
-+        return prev;
-+    }
-+
-+    private void doPut(final K key, final V value) {
-+        doRemoveByKey(key);
-+        doRemoveByValue(value);
-+        Node<K, V> node = rootNode[KEY];
-+        if (node == null) {
-+            // map is empty
-+            Node<K, V> root = new Node<K, V>(key, value);
-+            rootNode[KEY] = root;
-+            rootNode[VALUE] = root;
-+            grow();
-+
-+        } else {
-+            // add new mapping
-+            while (true) {
-+                int cmp = compare(key, node.getKey());
-+
-+                if (cmp == 0) {
-+                    // shouldn't happen
-+                    throw new IllegalArgumentException("Cannot store a duplicate key (\"" + key + "\") in this Map");
-+                } else if (cmp < 0) {
-+                    if (node.getLeft(KEY) != null) {
-+                        node = node.getLeft(KEY);
-+                    } else {
-+                        Node<K, V> newNode = new Node<K, V>(key, value);
-+
-+                        insertValue(newNode);
-+                        node.setLeft(newNode, KEY);
-+                        newNode.setParent(node, KEY);
-+                        doRedBlackInsert(newNode, KEY);
-+                        grow();
-+
-+                        break;
-+                    }
-+                } else { // cmp > 0
-+                    if (node.getRight(KEY) != null) {
-+                        node = node.getRight(KEY);
-+                    } else {
-+                        Node<K, V> newNode = new Node<K, V>(key, value);
-+
-+                        insertValue(newNode);
-+                        node.setRight(newNode, KEY);
-+                        newNode.setParent(node, KEY);
-+                        doRedBlackInsert(newNode, KEY);
-+                        grow();
-+
-+                        break;
-+                    }
-+                }
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Remove by key
-+     *
-+     * @param key the key
-+     * @return the key, if remove by value, or the value, if remove by
-+     *         key. null if the specified key or value could not be
-+     *         found
-+     */
-+    private V doRemoveByKey(final K key) {
-+        Node<K, V> node = lookup(key, KEY);
-+        V rval = null;
-+        if (node != null) {
-+            rval = node.getValue();
-+            doRedBlackDelete(node);
-+        }
-+        return rval;
-+    }
-+
-+    /**
-+     * Remove by value
-+     *
-+     * @param value the value
-+     * @return the key, if remove by value, or the value, if remove by
-+     *         key. null if the specified key or value could not be
-+     *         found
-+     */
-+    private K doRemoveByValue(final Comparable value) {
-+        Node<K, V> node = lookup(value, VALUE);
-+        K rval = null;
-+        if (node != null) {
-+            rval = node.getKey();
-+            doRedBlackDelete(node);
-+        }
-+        return rval;
-+    }
-+
-+    /**
-+     * do the actual lookup of a piece of data
-+     *
-+     * @param data  the key or value to be looked up
-+     * @param index the KEY or VALUE int
-+     * @return the desired Node, or null if there is no mapping of the
-+     *         specified data
-+     */
-+    private Node<K, V> lookup(final Comparable data, final int index) {
-+        Node<K, V> rval = null;
-+        Node<K, V> node = rootNode[index];
-+
-+        while (node != null) {
-+            int cmp = compare(data, node.getData(index));
-+            if (cmp == 0) {
-+                rval = node;
-+                break;
-+            } else {
-+                node = (cmp < 0) ? node.getLeft(index) : node.getRight(index);
-+            }
-+        }
-+
-+        return rval;
-+    }
-+
-+    /**
-+     * get the next larger node from the specified node
-+     *
-+     * @param node  the node to be searched from
-+     * @param index the KEY or VALUE int
-+     * @return the specified node
-+     */
-+    private Node<K, V> nextGreater(final Node<K, V> node, final int index) {
-+        Node<K, V> rval = null;
-+        if (node == null) {
-+            rval = null;
-+        } else if (node.getRight(index) != null) {
-+            // everything to the node's right is larger. The least of
-+            // the right node's descendants is the next larger node
-+            rval = leastNode(node.getRight(index), index);
-+        } else {
-+            // traverse up our ancestry until we find an ancestor that
-+            // is null or one whose left child is our ancestor. If we
-+            // find a null, then this node IS the largest node in the
-+            // tree, and there is no greater node. Otherwise, we are
-+            // the largest node in the subtree on that ancestor's left
-+            // ... and that ancestor is the next greatest node
-+            Node<K, V> parent = node.getParent(index);
-+            Node<K, V> child = node;
-+
-+            while ((parent != null) && (child == parent.getRight(index))) {
-+                child = parent;
-+                parent = parent.getParent(index);
-+            }
-+            rval = parent;
-+        }
-+        return rval;
-+    }
-+
-+    /**
-+     * get the next larger node from the specified node
-+     *
-+     * @param node  the node to be searched from
-+     * @param index the KEY or VALUE int
-+     * @return the specified node
-+     */
-+    private Node<K, V> nextSmaller(final Node<K, V> node, final int index) {
-+        Node<K, V> rval = null;
-+        if (node == null) {
-+            rval = null;
-+        } else if (node.getLeft(index) != null) {
-+            // everything to the node's left is smaller. The greatest of
-+            // the left node's descendants is the next smaller node
-+            rval = greatestNode(node.getLeft(index), index);
-+        } else {
-+            // traverse up our ancestry until we find an ancestor that
-+            // is null or one whose right child is our ancestor. If we
-+            // find a null, then this node IS the largest node in the
-+            // tree, and there is no greater node. Otherwise, we are
-+            // the largest node in the subtree on that ancestor's right
-+            // ... and that ancestor is the next greatest node
-+            Node<K, V> parent = node.getParent(index);
-+            Node<K, V> child = node;
-+
-+            while ((parent != null) && (child == parent.getLeft(index))) {
-+                child = parent;
-+                parent = parent.getParent(index);
-+            }
-+            rval = parent;
-+        }
-+        return rval;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Get the opposite index of the specified index
-+     *
-+     * @param index the KEY or VALUE int
-+     * @return VALUE (if KEY was specified), else KEY
-+     */
-+    private static int oppositeIndex(final int index) {
-+        // old trick ... to find the opposite of a value, m or n,
-+        // subtract the value from the sum of the two possible
-+        // values. (m + n) - m = n; (m + n) - n = m
-+        return SUM_OF_INDICES - index;
-+    }
-+
-+    /**
-+     * Compare two objects
-+     *
-+     * @param o1 the first object
-+     * @param o2 the second object
-+     * @return negative value if o1 < o2; 0 if o1 == o2; positive
-+     *         value if o1 > o2
-+     */
-+    private static int compare(final Comparable o1, final Comparable o2) {
-+        return o1.compareTo(o2);
-+    }
-+
-+    /**
-+     * Find the least node from a given node.
-+     *
-+     * @param node  the node from which we will start searching
-+     * @param index the KEY or VALUE int
-+     * @return the smallest node, from the specified node, in the
-+     *         specified mapping
-+     */
-+    private static <K extends Comparable,V extends Comparable> Node<K, V> leastNode(final Node<K, V> node, final int index) {
-+        Node<K, V> rval = node;
-+        if (rval != null) {
-+            while (rval.getLeft(index) != null) {
-+                rval = rval.getLeft(index);
-+            }
-+        }
-+        return rval;
-+    }
-+
-+    /**
-+     * Find the greatest node from a given node.
-+     *
-+     * @param node  the node from which we will start searching
-+     * @param index the KEY or VALUE int
-+     * @return the greatest node, from the specified node
-+     */
-+    private static <K extends Comparable,V extends Comparable> Node<K, V> greatestNode(final Node<K, V> node, final int index) {
-+        Node<K, V> rval = node;
-+        if (rval != null) {
-+            while (rval.getRight(index) != null) {
-+                rval = rval.getRight(index);
-+            }
-+        }
-+        return rval;
-+    }
-+
-+    /**
-+     * copy the color from one node to another, dealing with the fact
-+     * that one or both nodes may, in fact, be null
-+     *
-+     * @param from  the node whose color we're copying; may be null
-+     * @param to    the node whose color we're changing; may be null
-+     * @param index the KEY or VALUE int
-+     */
-+    private static void copyColor(final Node from, final Node to, final int index) {
-+        if (to != null) {
-+            if (from == null) {
-+                // by default, make it black
-+                to.setBlack(index);
-+            } else {
-+                to.copyColor(from, index);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * is the specified node red? if the node does not exist, no, it's
-+     * black, thank you
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static boolean isRed(final Node node, final int index) {
-+        return ((node == null) ? false : node.isRed(index));
-+    }
-+
-+    /**
-+     * is the specified black red? if the node does not exist, sure,
-+     * it's black, thank you
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static boolean isBlack(final Node node, final int index) {
-+        return ((node == null) ? true : node.isBlack(index));
-+    }
-+
-+    /**
-+     * force a node (if it exists) red
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static void makeRed(final Node node, final int index) {
-+        if (node != null) {
-+            node.setRed(index);
-+        }
-+    }
-+
-+    /**
-+     * force a node (if it exists) black
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static <K extends Comparable,V extends Comparable> void makeBlack(final Node<K, V> node, final int index) {
-+        if (node != null) {
-+            node.setBlack(index);
-+        }
-+    }
-+
-+    /**
-+     * get a node's grandparent. mind you, the node, its parent, or
-+     * its grandparent may not exist. no problem
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static <K extends Comparable,V extends Comparable> Node<K, V> getGrandParent(final Node<K, V> node, final int index) {
-+        return getParent(getParent(node, index), index);
-+    }
-+
-+    /**
-+     * get a node's parent. mind you, the node, or its parent, may not
-+     * exist. no problem
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static <K extends Comparable,V extends Comparable> Node<K, V> getParent(final Node<K, V> node, final int index) {
-+        return ((node == null) ? null : node.getParent(index));
-+    }
-+
-+    /**
-+     * get a node's right child. mind you, the node may not exist. no
-+     * problem
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static <K extends Comparable,V extends Comparable> Node<K, V> getRightChild(final Node<K, V> node, final int index) {
-+        return (node == null) ? null : node.getRight(index);
-+    }
-+
-+    /**
-+     * get a node's left child. mind you, the node may not exist. no
-+     * problem
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static <K extends Comparable,V extends Comparable> Node<K, V> getLeftChild(final Node<K, V> node, final int index) {
-+        return (node == null) ? null : node.getLeft(index);
-+    }
-+
-+    /**
-+     * is this node its parent's left child? mind you, the node, or
-+     * its parent, may not exist. no problem. if the node doesn't
-+     * exist ... it's its non-existent parent's left child. If the
-+     * node does exist but has no parent ... no, we're not the
-+     * non-existent parent's left child. Otherwise (both the specified
-+     * node AND its parent exist), check.
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static <K extends Comparable,V extends Comparable> boolean isLeftChild(final Node<K, V> node, final int index) {
-+        return (node == null) ? true : ((node.getParent(index) == null) ? false : (node == node.getParent(index).getLeft(index)));
-+    }
-+
-+    /**
-+     * is this node its parent's right child? mind you, the node, or
-+     * its parent, may not exist. no problem. if the node doesn't
-+     * exist ... it's its non-existent parent's right child. If the
-+     * node does exist but has no parent ... no, we're not the
-+     * non-existent parent's right child. Otherwise (both the
-+     * specified node AND its parent exist), check.
-+     *
-+     * @param node  the node (may be null) in question
-+     * @param index the KEY or VALUE int
-+     */
-+    private static <K extends Comparable,V extends Comparable> boolean isRightChild(final Node<K, V> node, final int index) {
-+        return (node == null) ? true : ((node.getParent(index) == null) ? false : (node == node.getParent(index).getRight(index)));
-+    }
-+
-+    /**
-+     * do a rotate left. standard fare in the world of balanced trees
-+     *
-+     * @param node  the node to be rotated
-+     * @param index the KEY or VALUE int
-+     */
-+    private void rotateLeft(final Node<K, V> node, final int index) {
-+        Node<K, V> rightChild = node.getRight(index);
-+        node.setRight(rightChild.getLeft(index), index);
-+
-+        if (rightChild.getLeft(index) != null) {
-+            rightChild.getLeft(index).setParent(node, index);
-+        }
-+        rightChild.setParent(node.getParent(index), index);
-+
-+        if (node.getParent(index) == null) {
-+            // node was the root ... now its right child is the root
-+            rootNode[index] = rightChild;
-+        } else if (node.getParent(index).getLeft(index) == node) {
-+            node.getParent(index).setLeft(rightChild, index);
-+        } else {
-+            node.getParent(index).setRight(rightChild, index);
-+        }
-+
-+        rightChild.setLeft(node, index);
-+        node.setParent(rightChild, index);
-+    }
-+
-+    /**
-+     * do a rotate right. standard fare in the world of balanced trees
-+     *
-+     * @param node  the node to be rotated
-+     * @param index the KEY or VALUE int
-+     */
-+    private void rotateRight(final Node<K, V> node, final int index) {
-+        Node<K, V> leftChild = node.getLeft(index);
-+        node.setLeft(leftChild.getRight(index), index);
-+        if (leftChild.getRight(index) != null) {
-+            leftChild.getRight(index).setParent(node, index);
-+        }
-+        leftChild.setParent(node.getParent(index), index);
-+
-+        if (node.getParent(index) == null) {
-+            // node was the root ... now its left child is the root
-+            rootNode[index] = leftChild;
-+        } else if (node.getParent(index).getRight(index) == node) {
-+            node.getParent(index).setRight(leftChild, index);
-+        } else {
-+            node.getParent(index).setLeft(leftChild, index);
-+        }
-+
-+        leftChild.setRight(node, index);
-+        node.setParent(leftChild, index);
-+    }
-+
-+    /**
-+     * complicated red-black insert stuff. Based on Sun's TreeMap
-+     * implementation, though it's barely recognizable any more
-+     *
-+     * @param insertedNode the node to be inserted
-+     * @param index        the KEY or VALUE int
-+     */
-+    private void doRedBlackInsert(final Node<K, V> insertedNode, final int index) {
-+        Node<K, V> currentNode = insertedNode;
-+        makeRed(currentNode, index);
-+
-+        while ((currentNode != null) && (currentNode != rootNode[index]) && (isRed(currentNode.getParent(index), index))) {
-+            if (isLeftChild(getParent(currentNode, index), index)) {
-+                Node<K, V> y = getRightChild(getGrandParent(currentNode, index), index);
-+
-+                if (isRed(y, index)) {
-+                    makeBlack(getParent(currentNode, index), index);
-+                    makeBlack(y, index);
-+                    makeRed(getGrandParent(currentNode, index), index);
-+
-+                    currentNode = getGrandParent(currentNode, index);
-+                } else {
-+                    if (isRightChild(currentNode, index)) {
-+                        currentNode = getParent(currentNode, index);
-+
-+                        rotateLeft(currentNode, index);
-+                    }
-+
-+                    makeBlack(getParent(currentNode, index), index);
-+                    makeRed(getGrandParent(currentNode, index), index);
-+
-+                    if (getGrandParent(currentNode, index) != null) {
-+                        rotateRight(getGrandParent(currentNode, index), index);
-+                    }
-+                }
-+            } else {
-+
-+                // just like clause above, except swap left for right
-+                Node<K, V> y = getLeftChild(getGrandParent(currentNode, index), index);
-+
-+                if (isRed(y, index)) {
-+                    makeBlack(getParent(currentNode, index), index);
-+                    makeBlack(y, index);
-+                    makeRed(getGrandParent(currentNode, index), index);
-+
-+                    currentNode = getGrandParent(currentNode, index);
-+                } else {
-+                    if (isLeftChild(currentNode, index)) {
-+                        currentNode = getParent(currentNode, index);
-+
-+                        rotateRight(currentNode, index);
-+                    }
-+
-+                    makeBlack(getParent(currentNode, index), index);
-+                    makeRed(getGrandParent(currentNode, index), index);
-+
-+                    if (getGrandParent(currentNode, index) != null) {
-+                        rotateLeft(getGrandParent(currentNode, index), index);
-+                    }
-+                }
-+            }
-+        }
-+
-+        makeBlack(rootNode[index], index);
-+    }
-+
-+    /**
-+     * complicated red-black delete stuff. Based on Sun's TreeMap
-+     * implementation, though it's barely recognizable any more
-+     *
-+     * @param deletedNode the node to be deleted
-+     */
-+    private void doRedBlackDelete(final Node<K, V> deletedNode) {
-+        for (int index = FIRST_INDEX; index < NUMBER_OF_INDICES; index++) {
-+            // if deleted node has both left and children, swap with
-+            // the next greater node
-+            if ((deletedNode.getLeft(index) != null) && (deletedNode.getRight(index) != null)) {
-+                swapPosition(nextGreater(deletedNode, index), deletedNode, index);
-+            }
-+
-+            Node<K, V> replacement = ((deletedNode.getLeft(index) != null) ? deletedNode.getLeft(index) : deletedNode.getRight(index));
-+
-+            if (replacement != null) {
-+                replacement.setParent(deletedNode.getParent(index), index);
-+
-+                if (deletedNode.getParent(index) == null) {
-+                    rootNode[index] = replacement;
-+                } else if (deletedNode == deletedNode.getParent(index).getLeft(index)) {
-+                    deletedNode.getParent(index).setLeft(replacement, index);
-+                } else {
-+                    deletedNode.getParent(index).setRight(replacement, index);
-+                }
-+
-+                deletedNode.setLeft(null, index);
-+                deletedNode.setRight(null, index);
-+                deletedNode.setParent(null, index);
-+
-+                if (isBlack(deletedNode, index)) {
-+                    doRedBlackDeleteFixup(replacement, index);
-+                }
-+            } else {
-+
-+                // replacement is null
-+                if (deletedNode.getParent(index) == null) {
-+
-+                    // empty tree
-+                    rootNode[index] = null;
-+                } else {
-+
-+                    // deleted node had no children
-+                    if (isBlack(deletedNode, index)) {
-+                        doRedBlackDeleteFixup(deletedNode, index);
-+                    }
-+
-+                    if (deletedNode.getParent(index) != null) {
-+                        if (deletedNode == deletedNode.getParent(index).getLeft(index)) {
-+                            deletedNode.getParent(index).setLeft(null, index);
-+                        } else {
-+                            deletedNode.getParent(index).setRight(null, index);
-+                        }
-+
-+                        deletedNode.setParent(null, index);
-+                    }
-+                }
-+            }
-+        }
-+        shrink();
-+    }
-+
-+    /**
-+     * complicated red-black delete stuff. Based on Sun's TreeMap
-+     * implementation, though it's barely recognizable any more. This
-+     * rebalances the tree (somewhat, as red-black trees are not
-+     * perfectly balanced -- perfect balancing takes longer)
-+     *
-+     * @param replacementNode the node being replaced
-+     * @param index           the KEY or VALUE int
-+     */
-+    private void doRedBlackDeleteFixup(final Node<K, V> replacementNode, final int index) {
-+        Node<K, V> currentNode = replacementNode;
-+
-+        while ((currentNode != rootNode[index]) && (isBlack(currentNode, index))) {
-+            if (isLeftChild(currentNode, index)) {
-+                Node<K, V> siblingNode = getRightChild(getParent(currentNode, index), index);
-+
-+                if (isRed(siblingNode, index)) {
-+                    makeBlack(siblingNode, index);
-+                    makeRed(getParent(currentNode, index), index);
-+                    rotateLeft(getParent(currentNode, index), index);
-+
-+                    siblingNode = getRightChild(getParent(currentNode, index), index);
-+                }
-+
-+                if (isBlack(getLeftChild(siblingNode, index), index) && isBlack(getRightChild(siblingNode, index), index)) {
-+                    makeRed(siblingNode, index);
-+
-+                    currentNode = getParent(currentNode, index);
-+                } else {
-+                    if (isBlack(getRightChild(siblingNode, index), index)) {
-+                        makeBlack(getLeftChild(siblingNode, index), index);
-+                        makeRed(siblingNode, index);
-+                        rotateRight(siblingNode, index);
-+
-+                        siblingNode = getRightChild(getParent(currentNode, index), index);
-+                    }
-+
-+                    copyColor(getParent(currentNode, index), siblingNode, index);
-+                    makeBlack(getParent(currentNode, index), index);
-+                    makeBlack(getRightChild(siblingNode, index), index);
-+                    rotateLeft(getParent(currentNode, index), index);
-+
-+                    currentNode = rootNode[index];
-+                }
-+            } else {
-+                Node<K, V> siblingNode = getLeftChild(getParent(currentNode, index), index);
-+
-+                if (isRed(siblingNode, index)) {
-+                    makeBlack(siblingNode, index);
-+                    makeRed(getParent(currentNode, index), index);
-+                    rotateRight(getParent(currentNode, index), index);
-+
-+                    siblingNode = getLeftChild(getParent(currentNode, index), index);
-+                }
-+
-+                if (isBlack(getRightChild(siblingNode, index), index) && isBlack(getLeftChild(siblingNode, index), index)) {
-+                    makeRed(siblingNode, index);
-+
-+                    currentNode = getParent(currentNode, index);
-+                } else {
-+                    if (isBlack(getLeftChild(siblingNode, index), index)) {
-+                        makeBlack(getRightChild(siblingNode, index), index);
-+                        makeRed(siblingNode, index);
-+                        rotateLeft(siblingNode, index);
-+
-+                        siblingNode = getLeftChild(getParent(currentNode, index), index);
-+                    }
-+
-+                    copyColor(getParent(currentNode, index), siblingNode, index);
-+                    makeBlack(getParent(currentNode, index), index);
-+                    makeBlack(getLeftChild(siblingNode, index), index);
-+                    rotateRight(getParent(currentNode, index), index);
-+
-+                    currentNode = rootNode[index];
-+                }
-+            }
-+        }
-+
-+        makeBlack(currentNode, index);
-+    }
-+
-+    /**
-+     * swap two nodes (except for their content), taking care of
-+     * special cases where one is the other's parent ... hey, it
-+     * happens.
-+     *
-+     * @param x     one node
-+     * @param y     another node
-+     * @param index the KEY or VALUE int
-+     */
-+    private void swapPosition(final Node<K, V> x, final Node<K, V> y, final int index) {
-+        // Save initial values.
-+        Node<K, V> xFormerParent = x.getParent(index);
-+        Node<K, V> xFormerLeftChild = x.getLeft(index);
-+        Node<K, V> xFormerRightChild = x.getRight(index);
-+        Node<K, V> yFormerParent = y.getParent(index);
-+        Node<K, V> yFormerLeftChild = y.getLeft(index);
-+        Node<K, V> yFormerRightChild = y.getRight(index);
-+        boolean xWasLeftChild = (x.getParent(index) != null) && (x == x.getParent(index).getLeft(index));
-+        boolean yWasLeftChild = (y.getParent(index) != null) && (y == y.getParent(index).getLeft(index));
-+
-+        // Swap, handling special cases of one being the other's parent.
-+        if (x == yFormerParent) { // x was y's parent
-+            x.setParent(y, index);
-+
-+            if (yWasLeftChild) {
-+                y.setLeft(x, index);
-+                y.setRight(xFormerRightChild, index);
-+            } else {
-+                y.setRight(x, index);
-+                y.setLeft(xFormerLeftChild, index);
-+            }
-+        } else {
-+            x.setParent(yFormerParent, index);
-+
-+            if (yFormerParent != null) {
-+                if (yWasLeftChild) {
-+                    yFormerParent.setLeft(x, index);
-+                } else {
-+                    yFormerParent.setRight(x, index);
-+                }
-+            }
-+
-+            y.setLeft(xFormerLeftChild, index);
-+            y.setRight(xFormerRightChild, index);
-+        }
-+
-+        if (y == xFormerParent) { // y was x's parent
-+            y.setParent(x, index);
-+
-+            if (xWasLeftChild) {
-+                x.setLeft(y, index);
-+                x.setRight(yFormerRightChild, index);
-+            } else {
-+                x.setRight(y, index);
-+                x.setLeft(yFormerLeftChild, index);
-+            }
-+        } else {
-+            y.setParent(xFormerParent, index);
-+
-+            if (xFormerParent != null) {
-+                if (xWasLeftChild) {
-+                    xFormerParent.setLeft(y, index);
-+                } else {
-+                    xFormerParent.setRight(y, index);
-+                }
-+            }
-+
-+            x.setLeft(yFormerLeftChild, index);
-+            x.setRight(yFormerRightChild, index);
-+        }
-+
-+        // Fix children's parent pointers
-+        if (x.getLeft(index) != null) {
-+            x.getLeft(index).setParent(x, index);
-+        }
-+
-+        if (x.getRight(index) != null) {
-+            x.getRight(index).setParent(x, index);
-+        }
-+
-+        if (y.getLeft(index) != null) {
-+            y.getLeft(index).setParent(y, index);
-+        }
-+
-+        if (y.getRight(index) != null) {
-+            y.getRight(index).setParent(y, index);
-+        }
-+
-+        x.swapColors(y, index);
-+
-+        // Check if root changed
-+        if (rootNode[index] == x) {
-+            rootNode[index] = y;
-+        } else if (rootNode[index] == y) {
-+            rootNode[index] = x;
-+        }
-+    }
-+
-+    /**
-+     * check if an object is fit to be proper input ... has to be
-+     * Comparable and non-null
-+     *
-+     * @param o the object being checked
-+     * @throws NullPointerException if o is null
-+     * @throws ClassCastException   if o is not Comparable
-+     */
-+    private static void checkNonNullComparable(final Object o) {
-+        if (o == null) {
-+            throw new NullPointerException("Cannot be null");
-+        }
-+        if (!(o instanceof Comparable)) {
-+            throw new ClassCastException("Must be Comparable");
-+        }
-+    }
-+
-+    /**
-+     * check a key for validity (non-null and implements Comparable)
-+     *
-+     * @param key the key to be checked
-+     * @throws NullPointerException if key is null
-+     * @throws ClassCastException   if key is not Comparable
-+     */
-+    private static void checkKey(final Object key) {
-+        checkNonNullComparable(key);
-+    }
-+
-+    /**
-+     * check a value for validity (non-null and implements Comparable)
-+     *
-+     * @param value the value to be checked
-+     * @throws NullPointerException if value is null
-+     * @throws ClassCastException   if value is not Comparable
-+     */
-+    private static void checkValue(final Object value) {
-+        checkNonNullComparable(value);
-+    }
-+
-+    /**
-+     * check a key and a value for validity (non-null and implements
-+     * Comparable)
-+     *
-+     * @param key   the key to be checked
-+     * @param value the value to be checked
-+     * @throws NullPointerException if key or value is null
-+     * @throws ClassCastException   if key or value is not Comparable
-+     */
-+    private static void checkKeyAndValue(final Object key, final Object value) {
-+        checkKey(key);
-+        checkValue(value);
-+    }
-+
-+    /**
-+     * increment the modification count -- used to check for
-+     * concurrent modification of the map through the map and through
-+     * an Iterator from one of its Set or Collection views
-+     */
-+    private void modify() {
-+        modifications++;
-+    }
-+
-+    /**
-+     * bump up the size and note that the map has changed
-+     */
-+    private void grow() {
-+        modify();
-+        nodeCount++;
-+    }
-+
-+    /**
-+     * decrement the size and note that the map has changed
-+     */
-+    private void shrink() {
-+        modify();
-+        nodeCount--;
-+    }
-+
-+    /**
-+     * insert a node by its value
-+     *
-+     * @param newNode the node to be inserted
-+     * @throws IllegalArgumentException if the node already exists
-+     *                                  in the value mapping
-+     */
-+    private void insertValue(final Node<K, V> newNode) throws IllegalArgumentException {
-+        Node<K, V> node = rootNode[VALUE];
-+
-+        while (true) {
-+            int cmp = compare(newNode.getData(VALUE), node.getData(VALUE));
-+
-+            if (cmp == 0) {
-+                throw new IllegalArgumentException("Cannot store a duplicate value (\"" + newNode.getData(VALUE) + "\") in this Map");
-+            } else if (cmp < 0) {
-+                if (node.getLeft(VALUE) != null) {
-+                    node = node.getLeft(VALUE);
-+                } else {
-+                    node.setLeft(newNode, VALUE);
-+                    newNode.setParent(node, VALUE);
-+                    doRedBlackInsert(newNode, VALUE);
-+
-+                    break;
-+                }
-+            } else { // cmp > 0
-+                if (node.getRight(VALUE) != null) {
-+                    node = node.getRight(VALUE);
-+                } else {
-+                    node.setRight(newNode, VALUE);
-+                    newNode.setParent(node, VALUE);
-+                    doRedBlackInsert(newNode, VALUE);
-+
-+                    break;
-+                }
-+            }
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares for equals as per the API.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal
-+     */
-+    private boolean doEquals(Object obj, final int type) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof Map == false) {
-+            return false;
-+        }
-+        Map other = (Map) obj;
-+        if (other.size() != size()) {
-+            return false;
-+        }
-+
-+        if (nodeCount > 0) {
-+            try {
-+                for (MapIterator it = new ViewMapIterator(this, type); it.hasNext();) {
-+                    Object key = it.next();
-+                    Object value = it.getValue();
-+                    if (value.equals(other.get(key)) == false) {
-+                        return false;
-+                    }
-+                }
-+            } catch (ClassCastException ex) {
-+                return false;
-+            } catch (NullPointerException ex) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Gets the hash code value for this map as per the API.
-+     *
-+     * @return the hash code value for this map
-+     */
-+    private int doHashCode(final int type) {
-+        int total = 0;
-+        if (nodeCount > 0) {
-+            for (MapIterator it = new ViewMapIterator(this, type); it.hasNext();) {
-+                Object key = it.next();
-+                Object value = it.getValue();
-+                total += (key.hashCode() ^ value.hashCode());
-+            }
-+        }
-+        return total;
-+    }
-+
-+    /**
-+     * Gets the string form of this map as per AbstractMap.
-+     *
-+     * @return the string form of this map
-+     */
-+    private String doToString(final int type) {
-+        if (nodeCount == 0) {
-+            return "{}";
-+        }
-+        StringBuffer buf = new StringBuffer(nodeCount * 32);
-+        buf.append('{');
-+        MapIterator it = new ViewMapIterator(this, type);
-+        boolean hasNext = it.hasNext();
-+        while (hasNext) {
-+            Object key = it.next();
-+            Object value = it.getValue();
-+            buf.append(key == this ? "(this Map)" : key).append('=').append(value == this ? "(this Map)" : value);
-+
-+            hasNext = it.hasNext();
-+            if (hasNext) {
-+                buf.append(", ");
-+            }
-+        }
-+
-+        buf.append('}');
-+        return buf.toString();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A view of this map.
-+     */
-+    static class View <K extends Comparable,V extends Comparable> extends AbstractSet {
-+
-+        /**
-+         * The parent map.
-+         */
-+        protected final TreeBidiMap main;
-+        /**
-+         * Whether to return KEY or VALUE order.
-+         */
-+        protected final int orderType;
-+        /**
-+         * Whether to return KEY, VALUE, MAPENTRY or INVERSEMAPENTRY data.
-+         */
-+        protected final int dataType;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param main      the main map
-+         * @param orderType the KEY or VALUE int for the order
-+         * @param dataType  the KEY, VALUE, MAPENTRY or INVERSEMAPENTRY int
-+         */
-+        View(final TreeBidiMap main, final int orderType, final int dataType) {
-+            super();
-+            this.main = main;
-+            this.orderType = orderType;
-+            this.dataType = dataType;
-+        }
-+
-+        public Iterator iterator() {
-+            return new ViewIterator(main, orderType, dataType);
-+        }
-+
-+        public int size() {
-+            return main.size();
-+        }
-+
-+        public boolean contains(final Object obj) {
-+            checkNonNullComparable(obj);
-+            return (main.lookup((Comparable) obj, dataType) != null);
-+        }
-+
-+        public boolean remove(final Object obj) {
-+            if (dataType == KEY) {
-+                return main.doRemoveByKey((K) obj) != null;
-+            } else {
-+                return main.doRemoveByValue((V) obj) != null;
-+            }
-+        }
-+
-+        public void clear() {
-+            main.clear();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * An iterator over the map.
-+     */
-+    static class ViewIterator implements OrderedIterator {
-+
-+        /**
-+         * The parent map.
-+         */
-+        protected final TreeBidiMap main;
-+        /**
-+         * Whether to return KEY or VALUE order.
-+         */
-+        protected final int orderType;
-+        /**
-+         * Whether to return KEY, VALUE, MAPENTRY or INVERSEMAPENTRY data.
-+         */
-+        protected final int dataType;
-+        /**
-+         * The last node returned by the iterator.
-+         */
-+        protected Node lastReturnedNode;
-+        /**
-+         * The next node to be returned by the iterator.
-+         */
-+        protected Node nextNode;
-+        /**
-+         * The previous node in the sequence returned by the iterator.
-+         */
-+        protected Node previousNode;
-+        /**
-+         * The modification count.
-+         */
-+        private int expectedModifications;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param main      the main map
-+         * @param orderType the KEY or VALUE int for the order
-+         * @param dataType  the KEY, VALUE, MAPENTRY or INVERSEMAPENTRY int
-+         */
-+        ViewIterator(final TreeBidiMap main, final int orderType, final int dataType) {
-+            super();
-+            this.main = main;
-+            this.orderType = orderType;
-+            this.dataType = dataType;
-+            expectedModifications = main.modifications;
-+            nextNode = leastNode(main.rootNode[orderType], orderType);
-+            lastReturnedNode = null;
-+            previousNode = null;
-+        }
-+
-+        public final boolean hasNext() {
-+            return (nextNode != null);
-+        }
-+
-+        public final Object next() {
-+            if (nextNode == null) {
-+                throw new NoSuchElementException();
-+            }
-+            if (main.modifications != expectedModifications) {
-+                throw new ConcurrentModificationException();
-+            }
-+            lastReturnedNode = nextNode;
-+            previousNode = nextNode;
-+            nextNode = main.nextGreater(nextNode, orderType);
-+            return doGetData();
-+        }
-+
-+        public boolean hasPrevious() {
-+            return (previousNode != null);
-+        }
-+
-+        public Object previous() {
-+            if (previousNode == null) {
-+                throw new NoSuchElementException();
-+            }
-+            if (main.modifications != expectedModifications) {
-+                throw new ConcurrentModificationException();
-+            }
-+            nextNode = lastReturnedNode;
-+            if (nextNode == null) {
-+                nextNode = main.nextGreater(previousNode, orderType);
-+            }
-+            lastReturnedNode = previousNode;
-+            previousNode = main.nextSmaller(previousNode, orderType);
-+            return doGetData();
-+        }
-+
-+        /**
-+         * Gets the data value for the lastReturnedNode field.
-+         *
-+         * @return the data value
-+         */
-+        protected Object doGetData() {
-+            switch (dataType) {
-+                case KEY:
-+                    return lastReturnedNode.getKey();
-+                case VALUE:
-+                    return lastReturnedNode.getValue();
-+                case MAPENTRY:
-+                    return lastReturnedNode;
-+                case INVERSEMAPENTRY:
-+                    return new UnmodifiableMapEntry(lastReturnedNode.getValue(), lastReturnedNode.getKey());
-+            }
-+            return null;
-+        }
-+
-+        public final void remove() {
-+            if (lastReturnedNode == null) {
-+                throw new IllegalStateException();
-+            }
-+            if (main.modifications != expectedModifications) {
-+                throw new ConcurrentModificationException();
-+            }
-+            main.doRedBlackDelete(lastReturnedNode);
-+            expectedModifications++;
-+            lastReturnedNode = null;
-+            if (nextNode == null) {
-+                previousNode = main.greatestNode(main.rootNode[orderType], orderType);
-+            } else {
-+                previousNode = main.nextSmaller(nextNode, orderType);
-+            }
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * An iterator over the map.
-+     */
-+    static class ViewMapIterator extends ViewIterator implements OrderedMapIterator {
-+
-+        private final int oppositeType;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param main      the main map
-+         * @param orderType the KEY or VALUE int for the order
-+         */
-+        ViewMapIterator(final TreeBidiMap main, final int orderType) {
-+            super(main, orderType, orderType);
-+            this.oppositeType = oppositeIndex(dataType);
-+        }
-+
-+        public Object getKey() {
-+            if (lastReturnedNode == null) {
-+                throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
-+            }
-+            return lastReturnedNode.getData(dataType);
-+        }
-+
-+        public Object getValue() {
-+            if (lastReturnedNode == null) {
-+                throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
-+            }
-+            return lastReturnedNode.getData(oppositeType);
-+        }
-+
-+        public Object setValue(final Object obj) {
-+            throw new UnsupportedOperationException();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A view of this map.
-+     */
-+    static class EntryView extends View {
-+
-+        private final int oppositeType;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param main      the main map
-+         * @param orderType the KEY or VALUE int for the order
-+         * @param dataType  the MAPENTRY or INVERSEMAPENTRY int for the returned data
-+         */
-+        EntryView(final TreeBidiMap main, final int orderType, final int dataType) {
-+            super(main, orderType, dataType);
-+            this.oppositeType = main.oppositeIndex(orderType);
-+        }
-+
-+        public boolean contains(Object obj) {
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry entry = (Map.Entry) obj;
-+            Object value = entry.getValue();
-+            Node node = main.lookup((Comparable) entry.getKey(), orderType);
-+            return (node != null && node.getData(oppositeType).equals(value));
-+        }
-+
-+        public boolean remove(Object obj) {
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry entry = (Map.Entry) obj;
-+            Object value = entry.getValue();
-+            Node node = main.lookup((Comparable) entry.getKey(), orderType);
-+            if (node != null && node.getData(oppositeType).equals(value)) {
-+                main.doRedBlackDelete(node);
-+                return true;
-+            }
-+            return false;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A node used to store the data.
-+     */
-+    static class Node <K extends Comparable,V extends Comparable> implements Map.Entry<K, V>, KeyValue<K, V> {
-+
-+        private K key;
-+        private V value;
-+        private Node<K, V>[] leftNode;
-+        private Node<K, V>[] rightNode;
-+        private Node<K, V>[] parentNode;
-+        private boolean[] blackColor;
-+        private int hashcodeValue;
-+        private boolean calculatedHashCode;
-+
-+        /**
-+         * Make a new cell with given key and value, and with null
-+         * links, and black (true) colors.
-+         *
-+         * @param key
-+         * @param value
-+         */
-+        Node(final K key, final V value) {
-+            super();
-+            this.key = key;
-+            this.value = value;
-+            leftNode = new Node[2];
-+            rightNode = new Node[2];
-+            parentNode = new Node[2];
-+            blackColor = new boolean[]{true, true};
-+            calculatedHashCode = false;
-+        }
-+
-+        /**
-+         * Get the specified data.
-+         *
-+         * @param index the KEY or VALUE int
-+         * @return the key or value
-+         */
-+        private Comparable getData(final int index) {
-+            if (index == KEY) {
-+                return key;
-+            } else {
-+                return value;
-+            }
-+        }
-+
-+        /**
-+         * Set this node's left node.
-+         *
-+         * @param node  the new left node
-+         * @param index the KEY or VALUE int
-+         */
-+        private void setLeft(final Node<K, V> node, final int index) {
-+            leftNode[index] = node;
-+        }
-+
-+        /**
-+         * Get the left node.
-+         *
-+         * @param index the KEY or VALUE int
-+         * @return the left node, may be null
-+         */
-+        private Node<K, V> getLeft(final int index) {
-+            return leftNode[index];
-+        }
-+
-+        /**
-+         * Set this node's right node.
-+         *
-+         * @param node  the new right node
-+         * @param index the KEY or VALUE int
-+         */
-+        private void setRight(final Node<K, V> node, final int index) {
-+            rightNode[index] = node;
-+        }
-+
-+        /**
-+         * Get the right node.
-+         *
-+         * @param index the KEY or VALUE int
-+         * @return the right node, may be null
-+         */
-+        private Node<K, V> getRight(final int index) {
-+            return rightNode[index];
-+        }
-+
-+        /**
-+         * Set this node's parent node.
-+         *
-+         * @param node  the new parent node
-+         * @param index the KEY or VALUE int
-+         */
-+        private void setParent(final Node<K, V> node, final int index) {
-+            parentNode[index] = node;
-+        }
-+
-+        /**
-+         * Get the parent node.
-+         *
-+         * @param index the KEY or VALUE int
-+         * @return the parent node, may be null
-+         */
-+        private Node<K, V> getParent(final int index) {
-+            return parentNode[index];
-+        }
-+
-+        /**
-+         * Exchange colors with another node.
-+         *
-+         * @param node  the node to swap with
-+         * @param index the KEY or VALUE int
-+         */
-+        private void swapColors(final Node<K, V> node, final int index) {
-+            // Swap colors -- old hacker's trick
-+            blackColor[index] ^= node.blackColor[index];
-+            node.blackColor[index] ^= blackColor[index];
-+            blackColor[index] ^= node.blackColor[index];
-+        }
-+
-+        /**
-+         * Is this node black?
-+         *
-+         * @param index the KEY or VALUE int
-+         * @return true if black (which is represented as a true boolean)
-+         */
-+        private boolean isBlack(final int index) {
-+            return blackColor[index];
-+        }
-+
-+        /**
-+         * Is this node red?
-+         *
-+         * @param index the KEY or VALUE int
-+         * @return true if non-black
-+         */
-+        private boolean isRed(final int index) {
-+            return !blackColor[index];
-+        }
-+
-+        /**
-+         * Make this node black.
-+         *
-+         * @param index the KEY or VALUE int
-+         */
-+        private void setBlack(final int index) {
-+            blackColor[index] = true;
-+        }
-+
-+        /**
-+         * Make this node red.
-+         *
-+         * @param index the KEY or VALUE int
-+         */
-+        private void setRed(final int index) {
-+            blackColor[index] = false;
-+        }
-+
-+        /**
-+         * Make this node the same color as another
-+         *
-+         * @param node  the node whose color we're adopting
-+         * @param index the KEY or VALUE int
-+         */
-+        private void copyColor(final Node<K, V> node, final int index) {
-+            blackColor[index] = node.blackColor[index];
-+        }
-+
-+        //-------------------------------------------------------------------
-+        /**
-+         * Gets the key.
-+         *
-+         * @return the key corresponding to this entry.
-+         */
-+        public K getKey() {
-+            return key;
-+        }
-+
-+        /**
-+         * Gets the value.
-+         *
-+         * @return the value corresponding to this entry.
-+         */
-+        public V getValue() {
-+            return value;
-+        }
-+
-+        /**
-+         * Optional operation that is not permitted in this implementation
-+         *
-+         * @param ignored
-+         * @return does not return
-+         * @throws UnsupportedOperationException always
-+         */
-+        public V setValue(final V ignored) throws UnsupportedOperationException {
-+            throw new UnsupportedOperationException("Map.Entry.setValue is not supported");
-+        }
-+
-+        /**
-+         * Compares the specified object with this entry for equality.
-+         * Returns true if the given object is also a map entry and
-+         * the two entries represent the same mapping.
-+         *
-+         * @param obj the object to be compared for equality with this entry.
-+         * @return true if the specified object is equal to this entry.
-+         */
-+        public boolean equals(final Object obj) {
-+            if (obj == this) {
-+                return true;
-+            }
-+            if (!(obj instanceof Map.Entry)) {
-+                return false;
-+            }
-+            Map.Entry e = (Map.Entry) obj;
-+            return key.equals(e.getKey()) && value.equals(e.getValue());
-+        }
-+
-+        /**
-+         * @return the hash code value for this map entry.
-+         */
-+        public int hashCode() {
-+            if (!calculatedHashCode) {
-+                hashcodeValue = key.hashCode() ^ value.hashCode();
-+                calculatedHashCode = true;
-+            }
-+            return hashcodeValue;
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A node used to store the data.
-+     */
-+    static class Inverse <K extends Comparable,V extends Comparable> implements OrderedBidiMap<V, K> {
-+
-+        /**
-+         * The parent map.
-+         */
-+        private final TreeBidiMap<K, V> main;
-+        /**
-+         * Store the keySet once created.
-+         */
-+        private Set keySet;
-+        /**
-+         * Store the valuesSet once created.
-+         */
-+        private Set valuesSet;
-+        /**
-+         * Store the entrySet once created.
-+         */
-+        private Set entrySet;
-+
-+        /**
-+         * Constructor.
-+         *
-+         * @param main the main map
-+         */
-+        Inverse(final TreeBidiMap<K, V> main) {
-+            super();
-+            this.main = main;
-+        }
-+
-+        public int size() {
-+            return main.size();
-+        }
-+
-+        public boolean isEmpty() {
-+            return main.isEmpty();
-+        }
-+
-+        public K get(final Object key) {
-+            return main.getKey((V) key);
-+        }
-+
-+        public V getKey(final Object value) {
-+            return main.get(value);
-+        }
-+
-+        public boolean containsKey(final Object key) {
-+            return main.containsValue(key);
-+        }
-+
-+        public boolean containsValue(final Object value) {
-+            return main.containsKey(value);
-+        }
-+
-+        public V firstKey() {
-+            if (main.nodeCount == 0) {
-+                throw new NoSuchElementException("Map is empty");
-+            }
-+            return main.leastNode(main.rootNode[VALUE], VALUE).getValue();
-+        }
-+
-+        public V lastKey() {
-+            if (main.nodeCount == 0) {
-+                throw new NoSuchElementException("Map is empty");
-+            }
-+            return main.greatestNode(main.rootNode[VALUE], VALUE).getValue();
-+        }
-+
-+        public V nextKey(V key) {
-+            checkKey(key);
-+            Node<K, V> node = main.nextGreater(main.lookup((Comparable) key, VALUE), VALUE);
-+            return (node == null ? null : node.getValue());
-+        }
-+
-+        public V previousKey(V key) {
-+            checkKey(key);
-+            Node<K, V> node = main.nextSmaller(main.lookup((Comparable) key, VALUE), VALUE);
-+            return (node == null ? null : node.getValue());
-+        }
-+
-+        public K put(final V key, final K value) {
-+            return main.doPutByValue(value, key);
-+        }
-+
-+        public void putAll(Map<? extends V, ? extends K> map) {
-+            Iterator it = map.entrySet().iterator();
-+            while (it.hasNext()) {
-+                Map.Entry entry = (Map.Entry) it.next();
-+                put((V) entry.getKey(), (K) entry.getValue());
-+            }
-+        }
-+
-+        public K remove(final Object key) {
-+            return main.removeValue((V) key);
-+        }
-+
-+        public V removeValue(final Object value) {
-+            return main.remove(value);
-+        }
-+
-+        public void clear() {
-+            main.clear();
-+        }
-+
-+        public Set<V> keySet() {
-+            if (keySet == null) {
-+                keySet = new View(main, VALUE, VALUE);
-+            }
-+            return keySet;
-+        }
-+
-+        public Set<K> values() {
-+            if (valuesSet == null) {
-+                valuesSet = new View(main, VALUE, KEY);
-+            }
-+            return valuesSet;
-+        }
-+
-+        public Set<Map.Entry<V, K>> entrySet() {
-+            if (entrySet == null) {
-+                return new EntryView(main, VALUE, INVERSEMAPENTRY);
-+            }
-+            return entrySet;
-+        }
-+
-+        public MapIterator<V, K> mapIterator() {
-+            if (isEmpty()) {
-+                return EmptyOrderedMapIterator.INSTANCE;
-+            }
-+            return new ViewMapIterator(main, VALUE);
-+        }
-+
-+        public OrderedMapIterator<V, K> orderedMapIterator() {
-+            if (isEmpty()) {
-+                return EmptyOrderedMapIterator.INSTANCE;
-+            }
-+            return new ViewMapIterator(main, VALUE);
-+        }
-+
-+        public BidiMap<K, V> inverseBidiMap() {
-+            return main;
-+        }
-+
-+        public OrderedBidiMap<K, V> inverseOrderedBidiMap() {
-+            return main;
-+        }
-+
-+        public boolean equals(Object obj) {
-+            return main.doEquals(obj, VALUE);
-+        }
-+
-+        public int hashCode() {
-+            return main.doHashCode(VALUE);
-+        }
-+
-+        public String toString() {
-+            return main.doToString(VALUE);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/UnmodifiableBidiMap.java
-@@ -0,0 +1,120 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.BidiMap;
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableMapIterator;
-+import org.apache.commons.collections15.map.UnmodifiableEntrySet;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>BidiMap</code> to ensure it can't be altered.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableBidiMap <K,V> extends AbstractBidiMapDecorator<K, V> implements Unmodifiable {
-+
-+    /**
-+     * The inverse unmodifiable map
-+     */
-+    private UnmodifiableBidiMap<V, K> inverse;
-+
-+    /**
-+     * Factory method to create an unmodifiable map.
-+     * <p/>
-+     * If the map passed in is already unmodifiable, it is returned.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @return an unmodifiable BidiMap
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> BidiMap<K, V> decorate(BidiMap<K, V> map) {
-+        if (map instanceof Unmodifiable) {
-+            return map;
-+        }
-+        return new UnmodifiableBidiMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    private UnmodifiableBidiMap(BidiMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V put(K key, V value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = super.entrySet();
-+        return UnmodifiableEntrySet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = super.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Set<V> values() {
-+        Set<V> coll = super.values();
-+        return (Set<V>) UnmodifiableSet.decorate(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K removeValue(Object value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public MapIterator<K, V> mapIterator() {
-+        MapIterator<K, V> it = getBidiMap().mapIterator();
-+        return UnmodifiableMapIterator.decorate(it);
-+    }
-+
-+    public BidiMap<V, K> inverseBidiMap() {
-+        if (inverse == null) {
-+            inverse = new UnmodifiableBidiMap<V, K>(getBidiMap().inverseBidiMap());
-+            inverse.inverse = this;
-+        }
-+        return inverse;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/UnmodifiableOrderedBidiMap.java
-@@ -0,0 +1,127 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.*;
-+import org.apache.commons.collections15.iterators.UnmodifiableOrderedMapIterator;
-+import org.apache.commons.collections15.map.UnmodifiableEntrySet;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>OrderedBidiMap</code> to ensure it can't be altered.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableOrderedBidiMap <K,V> extends AbstractOrderedBidiMapDecorator<K, V> implements Unmodifiable {
-+
-+    /**
-+     * The inverse unmodifiable map
-+     */
-+    private UnmodifiableOrderedBidiMap<V, K> inverse;
-+
-+    /**
-+     * Factory method to create an unmodifiable map.
-+     * <p/>
-+     * If the map passed in is already unmodifiable, it is returned.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @return an unmodifiable OrderedBidiMap
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> OrderedBidiMap<K, V> decorate(OrderedBidiMap<K, V> map) {
-+        if (map instanceof Unmodifiable) {
-+            return map;
-+        }
-+        return new UnmodifiableOrderedBidiMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    private UnmodifiableOrderedBidiMap(OrderedBidiMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V put(K key, V value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = super.entrySet();
-+        return UnmodifiableEntrySet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = super.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Set<V> values() {
-+        Set<V> coll = super.values();
-+        return UnmodifiableSet.decorate(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K removeValue(Object value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public MapIterator<K, V> mapIterator() {
-+        return orderedMapIterator();
-+    }
-+
-+    public BidiMap<V, K> inverseBidiMap() {
-+        return inverseOrderedBidiMap();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        OrderedMapIterator<K, V> it = getOrderedBidiMap().orderedMapIterator();
-+        return UnmodifiableOrderedMapIterator.decorate(it);
-+    }
-+
-+    public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
-+        if (inverse == null) {
-+            inverse = new UnmodifiableOrderedBidiMap<V, K>(getOrderedBidiMap().inverseOrderedBidiMap());
-+            inverse.inverse = this;
-+        }
-+        return inverse;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/UnmodifiableSortedBidiMap.java
-@@ -0,0 +1,149 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.bidimap;
-+
-+import org.apache.commons.collections15.*;
-+import org.apache.commons.collections15.iterators.UnmodifiableOrderedMapIterator;
-+import org.apache.commons.collections15.map.UnmodifiableEntrySet;
-+import org.apache.commons.collections15.map.UnmodifiableSortedMap;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.util.Map;
-+import java.util.Set;
-+import java.util.SortedMap;
-+
-+/**
-+ * Decorates another <code>SortedBidiMap</code> to ensure it can't be altered.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:19 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableSortedBidiMap <K,V> extends AbstractSortedBidiMapDecorator<K, V> implements Unmodifiable {
-+
-+    /**
-+     * The inverse unmodifiable map
-+     */
-+    private UnmodifiableSortedBidiMap<V, K> inverse;
-+
-+    /**
-+     * Factory method to create an unmodifiable map.
-+     * <p/>
-+     * If the map passed in is already unmodifiable, it is returned.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @return an unmodifiable SortedBidiMap
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> SortedBidiMap<K, V> decorate(SortedBidiMap<K, V> map) {
-+        if (map instanceof Unmodifiable) {
-+            return map;
-+        }
-+        return new UnmodifiableSortedBidiMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    private UnmodifiableSortedBidiMap(SortedBidiMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V put(K key, V value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = super.entrySet();
-+        return UnmodifiableEntrySet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = super.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Set<V> values() {
-+        Set<V> coll = super.values();
-+        return UnmodifiableSet.decorate(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K removeValue(Object value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public MapIterator<K, V> mapIterator() {
-+        return orderedMapIterator();
-+    }
-+
-+    public BidiMap<V, K> inverseBidiMap() {
-+        return inverseSortedBidiMap();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        OrderedMapIterator<K, V> it = getSortedBidiMap().orderedMapIterator();
-+        return UnmodifiableOrderedMapIterator.decorate(it);
-+    }
-+
-+    public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
-+        return inverseSortedBidiMap();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedBidiMap<V, K> inverseSortedBidiMap() {
-+        if (inverse == null) {
-+            inverse = new UnmodifiableSortedBidiMap<V, K>(getSortedBidiMap().inverseSortedBidiMap());
-+            inverse.inverse = this;
-+        }
-+        return inverse;
-+    }
-+
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        SortedMap<K, V> sm = getSortedBidiMap().subMap(fromKey, toKey);
-+        return UnmodifiableSortedMap.decorate(sm);
-+    }
-+
-+    public SortedMap<K, V> headMap(K toKey) {
-+        SortedMap<K, V> sm = getSortedBidiMap().headMap(toKey);
-+        return UnmodifiableSortedMap.decorate(sm);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        SortedMap<K, V> sm = getSortedBidiMap().tailMap(fromKey);
-+        return UnmodifiableSortedMap.decorate(sm);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/bidimap/package.html
-@@ -0,0 +1,47 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:19 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link org.apache.commons.collections.BidiMap BidiMap},
-+{@link org.apache.commons.collections.OrderedBidiMap OrderedBidiMap} and 
-+{@link org.apache.commons.collections.SortedBidiMap SortedBidiMap} interfaces.
-+A BidiMap is an extension to Map that allows keys and values to be looked up with equal ease.
-+One example usage is a system communicating to a legacy datasource that must convert codes
-+from the new format to the old format and vice versa.
-+<p>
-+The following implementations are provided in the package:
-+<ul>
-+<li>DualHashBidiMap - uses two HashMaps to implement BidiMap
-+<li>DualTreeBidiMap - uses two TreeMaps to implement SortedBidiMap
-+<li>TreeBidiMap - red-black tree implementation of OrderedBidiMap
-+</ul>
-+<p>
-+The following decorators are provided in the package:
-+<ul>
-+<li>Unmodifiable - ensures the map cannot be altered
-+<!--
-+<li>Synchronized - synchronizes method access for multi-threaded environments
-+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
-+<li>Typed - ensures that only elements that are of a specific type can be added
-+<li>Transformed - transforms each element added
-+<li>FixedSize - ensures that the size of the map cannot change
-+<li>Lazy - creates objects in the map on demand
-+<li>ListOrdered - ensures that insertion order is retained-->
-+</ul>
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/AbstractBufferDecorator.java
-@@ -0,0 +1,70 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.collection.AbstractCollectionDecorator;
-+
-+/**
-+ * Decorates another <code>Buffer</code> to provide additional behaviour.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated buffer.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractBufferDecorator <E> extends AbstractCollectionDecorator<E> implements Buffer<E> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractBufferDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    protected AbstractBufferDecorator(Buffer<E> buffer) {
-+        super(buffer);
-+    }
-+
-+    /**
-+     * Gets the buffer being decorated.
-+     *
-+     * @return the decorated buffer
-+     */
-+    protected Buffer<E> getBuffer() {
-+        return (Buffer<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E get() {
-+        return getBuffer().get();
-+    }
-+
-+    public E remove() {
-+        return getBuffer().remove();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/BlockingBuffer.java
-@@ -0,0 +1,118 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.BufferUnderflowException;
-+
-+import java.util.Collection;
-+
-+/**
-+ * Decorates another <code>Buffer</code> to make {@link #get()} and
-+ * {@link #remove()} block when the <code>Buffer</code> is empty.
-+ * <p/>
-+ * If either <code>get</code> or <code>remove</code> is called on an empty
-+ * <code>Buffer</code>, the calling thread waits for notification that
-+ * an <code>add</code> or <code>addAll</code> operation has completed.
-+ * <p/>
-+ * When one or more entries are added to an empty <code>Buffer</code>,
-+ * all threads blocked in <code>get</code> or <code>remove</code> are notified.
-+ * There is no guarantee that concurrent blocked <code>get</code> or
-+ * <code>remove</code> requests will be "unblocked" and receive data in the
-+ * order that they arrive.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Janek Bogucki
-+ * @author Matt Hall, John Watkinson, Phil Steitz
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class BlockingBuffer <E> extends SynchronizedBuffer<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 1719328905017860541L;
-+
-+    /**
-+     * Factory method to create a blocking buffer.
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @return a new blocking Buffer
-+     * @throws IllegalArgumentException if buffer is null
-+     */
-+    public static <E> Buffer<E> decorate(Buffer<E> buffer) {
-+        return new BlockingBuffer<E>(buffer);
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @throws IllegalArgumentException if the buffer is null
-+     */
-+    protected BlockingBuffer(Buffer<E> buffer) {
-+        super(buffer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E o) {
-+        synchronized (lock) {
-+            boolean result = collection.add(o);
-+            notifyAll();
-+            return result;
-+        }
-+    }
-+
-+    public boolean addAll(Collection<? extends E> c) {
-+        synchronized (lock) {
-+            boolean result = collection.addAll(c);
-+            notifyAll();
-+            return result;
-+        }
-+    }
-+
-+    public E get() {
-+        synchronized (lock) {
-+            while (collection.isEmpty()) {
-+                try {
-+                    wait();
-+                } catch (InterruptedException e) {
-+                    throw new BufferUnderflowException();
-+                }
-+            }
-+            return getBuffer().get();
-+        }
-+    }
-+
-+    public E remove() {
-+        synchronized (lock) {
-+            while (collection.isEmpty()) {
-+                try {
-+                    wait();
-+                } catch (InterruptedException e) {
-+                    throw new BufferUnderflowException();
-+                }
-+            }
-+            return getBuffer().remove();
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/BoundedFifoBuffer.java
-@@ -0,0 +1,363 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.BoundedCollection;
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.BufferOverflowException;
-+import org.apache.commons.collections15.BufferUnderflowException;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * The BoundedFifoBuffer is a very efficient implementation of
-+ * Buffer that does not alter the size of the buffer at runtime.
-+ * <p/>
-+ * The removal order of a <code>BoundedFifoBuffer</code> is based on the
-+ * insertion order; elements are removed in the same order in which they
-+ * were added.  The iteration order is the same as the removal order.
-+ * <p/>
-+ * The {@link #add(Object)}, {@link #remove()} and {@link #get()} operations
-+ * all perform in constant time.  All other operations perform in linear
-+ * time or worse.
-+ * <p/>
-+ * Note that this implementation is not synchronized.  The following can be
-+ * used to provide synchronized access to your <code>BoundedFifoBuffer</code>:
-+ * <pre>
-+ *   Buffer fifo = BufferUtils.synchronizedBuffer(new BoundedFifoBuffer());
-+ * </pre>
-+ * <p/>
-+ * This buffer prevents null objects from being added.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Avalon
-+ * @author Berin Loritsch
-+ * @author Paul Jack
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Herve Quiroz
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0 (previously in main package v2.1)
-+ */
-+public class BoundedFifoBuffer <E> extends AbstractCollection<E> implements Buffer<E>, BoundedCollection<E>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 5603722811189451017L;
-+
-+    private transient E[] elements;
-+    private transient int start = 0;
-+    private transient int end = 0;
-+    private transient boolean full = false;
-+    private final int maxElements;
-+
-+    /**
-+     * Constructs a new <code>BoundedFifoBuffer</code> big enough to hold
-+     * 32 elements.
-+     */
-+    public BoundedFifoBuffer() {
-+        this(32);
-+    }
-+
-+    /**
-+     * Constructs a new <code>BoundedFifoBuffer</code> big enough to hold
-+     * the specified number of elements.
-+     *
-+     * @param size the maximum number of elements for this fifo
-+     * @throws IllegalArgumentException if the size is less than 1
-+     */
-+    public BoundedFifoBuffer(int size) {
-+        if (size <= 0) {
-+            throw new IllegalArgumentException("The size must be greater than 0");
-+        }
-+        elements = (E[]) new Object[size];
-+        maxElements = elements.length;
-+    }
-+
-+    /**
-+     * Constructs a new <code>BoundedFifoBuffer</code> big enough to hold all
-+     * of the elements in the specified collection. That collection's
-+     * elements will also be added to the buffer.
-+     *
-+     * @param coll the collection whose elements to add, may not be null
-+     * @throws NullPointerException if the collection is null
-+     */
-+    public BoundedFifoBuffer(Collection<E> coll) {
-+        this(coll.size());
-+        addAll(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the buffer out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeInt(size());
-+        for (Iterator it = iterator(); it.hasNext();) {
-+            out.writeObject(it.next());
-+        }
-+    }
-+
-+    /**
-+     * Read the buffer in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        elements = (E[]) new Object[maxElements];
-+        int size = in.readInt();
-+        for (int i = 0; i < size; i++) {
-+            elements[i] = (E) in.readObject();
-+        }
-+        start = 0;
-+        full = (size == maxElements);
-+        if (full) {
-+            end = 0;
-+        } else {
-+            end = size;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the number of elements stored in the buffer.
-+     *
-+     * @return this buffer's size
-+     */
-+    public int size() {
-+        int size = 0;
-+
-+        if (end < start) {
-+            size = maxElements - start + end;
-+        } else if (end == start) {
-+            size = (full ? maxElements : 0);
-+        } else {
-+            size = end - start;
-+        }
-+
-+        return size;
-+    }
-+
-+    /**
-+     * Returns true if this buffer is empty; false otherwise.
-+     *
-+     * @return true if this buffer is empty
-+     */
-+    public boolean isEmpty() {
-+        return size() == 0;
-+    }
-+
-+    /**
-+     * Returns true if this collection is full and no new elements can be added.
-+     *
-+     * @return <code>true</code> if the collection is full
-+     */
-+    public boolean isFull() {
-+        return size() == maxElements;
-+    }
-+
-+    /**
-+     * Gets the maximum size of the collection (the bound).
-+     *
-+     * @return the maximum number of elements the collection can hold
-+     */
-+    public int maxSize() {
-+        return maxElements;
-+    }
-+
-+    /**
-+     * Clears this buffer.
-+     */
-+    public void clear() {
-+        full = false;
-+        start = 0;
-+        end = 0;
-+        Arrays.fill(elements, null);
-+    }
-+
-+    /**
-+     * Adds the given element to this buffer.
-+     *
-+     * @param element the element to add
-+     * @return true, always
-+     * @throws NullPointerException    if the given element is null
-+     * @throws BufferOverflowException if this buffer is full
-+     */
-+    public boolean add(E element) {
-+        if (null == element) {
-+            throw new NullPointerException("Attempted to add null object to buffer");
-+        }
-+
-+        if (full) {
-+            throw new BufferOverflowException("The buffer cannot hold more than " + maxElements + " objects.");
-+        }
-+
-+        elements[end++] = element;
-+
-+        if (end >= maxElements) {
-+            end = 0;
-+        }
-+
-+        if (end == start) {
-+            full = true;
-+        }
-+
-+        return true;
-+    }
-+
-+    /**
-+     * Returns the least recently inserted element in this buffer.
-+     *
-+     * @return the least recently inserted element
-+     * @throws BufferUnderflowException if the buffer is empty
-+     */
-+    public E get() {
-+        if (isEmpty()) {
-+            throw new BufferUnderflowException("The buffer is already empty");
-+        }
-+
-+        return elements[start];
-+    }
-+
-+    /**
-+     * Removes the least recently inserted element from this buffer.
-+     *
-+     * @return the least recently inserted element
-+     * @throws BufferUnderflowException if the buffer is empty
-+     */
-+    public E remove() {
-+        if (isEmpty()) {
-+            throw new BufferUnderflowException("The buffer is already empty");
-+        }
-+
-+        E element = elements[start];
-+
-+        if (null != element) {
-+            elements[start++] = null;
-+
-+            if (start >= maxElements) {
-+                start = 0;
-+            }
-+
-+            full = false;
-+        }
-+
-+        return element;
-+    }
-+
-+    /**
-+     * Increments the internal index.
-+     *
-+     * @param index the index to increment
-+     * @return the updated index
-+     */
-+    private int increment(int index) {
-+        index++;
-+        if (index >= maxElements) {
-+            index = 0;
-+        }
-+        return index;
-+    }
-+
-+    /**
-+     * Decrements the internal index.
-+     *
-+     * @param index the index to decrement
-+     * @return the updated index
-+     */
-+    private int decrement(int index) {
-+        index--;
-+        if (index < 0) {
-+            index = maxElements - 1;
-+        }
-+        return index;
-+    }
-+
-+    /**
-+     * Returns an iterator over this buffer's elements.
-+     *
-+     * @return an iterator over this buffer's elements
-+     */
-+    public Iterator<E> iterator() {
-+        return new Iterator() {
-+
-+            private int index = start;
-+            private int lastReturnedIndex = -1;
-+            private boolean isFirst = full;
-+
-+            public boolean hasNext() {
-+                return isFirst || (index != end);
-+
-+            }
-+
-+            public E next() {
-+                if (!hasNext()) {
-+                    throw new NoSuchElementException();
-+                }
-+                isFirst = false;
-+                lastReturnedIndex = index;
-+                index = increment(index);
-+                return elements[lastReturnedIndex];
-+            }
-+
-+            public void remove() {
-+                if (lastReturnedIndex == -1) {
-+                    throw new IllegalStateException();
-+                }
-+
-+                // First element can be removed quickly
-+                if (lastReturnedIndex == start) {
-+                    BoundedFifoBuffer.this.remove();
-+                    lastReturnedIndex = -1;
-+                    return;
-+                }
-+
-+                // Other elements require us to shift the subsequent elements
-+                int i = lastReturnedIndex + 1;
-+                while (i != end) {
-+                    if (i >= maxElements) {
-+                        elements[i - 1] = elements[0];
-+                        i = 0;
-+                    } else {
-+                        elements[i - 1] = elements[i];
-+                        i++;
-+                    }
-+                }
-+
-+                lastReturnedIndex = -1;
-+                end = decrement(end);
-+                elements[end] = null;
-+                full = false;
-+                index = decrement(index);
-+            }
-+
-+        };
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/CircularFifoBuffer.java
-@@ -0,0 +1,97 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import java.util.Collection;
-+
-+/**
-+ * CircularFifoBuffer is a first in first out buffer with a fixed size that
-+ * replaces its oldest element if full.
-+ * <p/>
-+ * The removal order of a <code>CircularFifoBuffer</code> is based on the
-+ * insertion order; elements are removed in the same order in which they
-+ * were added.  The iteration order is the same as the removal order.
-+ * <p/>
-+ * The {@link #add(Object)}, {@link #remove()} and {@link #get()} operations
-+ * all perform in constant time.  All other operations perform in linear
-+ * time or worse.
-+ * <p/>
-+ * Note that this implementation is not synchronized.  The following can be
-+ * used to provide synchronized access to your <code>CircularFifoBuffer</code>:
-+ * <pre>
-+ *   Buffer fifo = BufferUtils.synchronizedBuffer(new CircularFifoBuffer());
-+ * </pre>
-+ * <p/>
-+ * This buffer prevents null objects from being added.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stefano Fornari
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class CircularFifoBuffer <E> extends BoundedFifoBuffer<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -8423413834657610406L;
-+
-+    /**
-+     * Constructor that creates a buffer with the default size of 32.
-+     */
-+    public CircularFifoBuffer() {
-+        super(32);
-+    }
-+
-+    /**
-+     * Constructor that creates a buffer with the specified size.
-+     *
-+     * @param size the size of the buffer (cannot be changed)
-+     * @throws IllegalArgumentException if the size is less than 1
-+     */
-+    public CircularFifoBuffer(int size) {
-+        super(size);
-+    }
-+
-+    /**
-+     * Constructor that creates a buffer from the specified collection.
-+     * The collection size also sets the buffer size
-+     *
-+     * @param coll the collection to copy into the buffer, may not be null
-+     * @throws NullPointerException if the collection is null
-+     */
-+    public CircularFifoBuffer(Collection<E> coll) {
-+        super(coll);
-+    }
-+
-+    /**
-+     * If the buffer is full, the least recently added element is discarded so
-+     * that a new element can be inserted.
-+     *
-+     * @param element the element to add
-+     * @return true, always
-+     */
-+    public boolean add(E element) {
-+        if (isFull()) {
-+            remove();
-+        }
-+        return super.add(element);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/PredicatedBuffer.java
-@@ -0,0 +1,98 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.collection.PredicatedCollection;
-+
-+/**
-+ * Decorates another <code>Buffer</code> to validate that additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This buffer exists to provide validation for the decorated buffer.
-+ * It is normally created to decorate an empty buffer.
-+ * If an object cannot be added to the buffer, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null entries are added to the buffer.
-+ * <pre>Buffer buffer = PredicatedBuffer.decorate(new UnboundedFifoBuffer(), NotNullPredicate.INSTANCE);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedBuffer <E> extends PredicatedCollection<E> implements Buffer<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 2307609000539943581L;
-+
-+    /**
-+     * Factory method to create a predicated (validating) buffer.
-+     * <p/>
-+     * If there are any elements already in the buffer being decorated, they
-+     * are validated.
-+     *
-+     * @param buffer    the buffer to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @return a new predicated Buffer
-+     * @throws IllegalArgumentException if buffer or predicate is null
-+     * @throws IllegalArgumentException if the buffer contains invalid elements
-+     */
-+    public static <E> Buffer<E> decorate(Buffer<E> buffer, Predicate<? super E> predicate) {
-+        return new PredicatedBuffer(buffer, predicate);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are validated.
-+     *
-+     * @param buffer    the buffer to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if buffer or predicate is null
-+     * @throws IllegalArgumentException if the buffer contains invalid elements
-+     */
-+    protected PredicatedBuffer(Buffer<E> buffer, Predicate<? super E> predicate) {
-+        super(buffer, predicate);
-+    }
-+
-+    /**
-+     * Gets the buffer being decorated.
-+     *
-+     * @return the decorated buffer
-+     */
-+    protected Buffer<E> getBuffer() {
-+        return (Buffer<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E get() {
-+        return getBuffer().get();
-+    }
-+
-+    public E remove() {
-+        return getBuffer().remove();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/PriorityBuffer.java
-@@ -0,0 +1,536 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.BufferUnderflowException;
-+
-+import java.util.AbstractCollection;
-+import java.util.Comparator;
-+import java.util.Iterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * Binary heap implementation of <code>Buffer</code> that provides for
-+ * removal based on <code>Comparator</code> ordering.
-+ * <p/>
-+ * The removal order of a binary heap is based on either the natural sort
-+ * order of its elements or a specified {@link Comparator}.  The
-+ * {@link #remove()} method always returns the first element as determined
-+ * by the sort order.  (The <code>ascendingOrder</code> flag in the constructors
-+ * can be used to reverse the sort order, in which case {@link #remove()}
-+ * will always remove the last element.)  The removal order is
-+ * <i>not</i> the same as the order of iteration; elements are
-+ * returned by the iterator in no particular order.
-+ * <p/>
-+ * The {@link #add(Object)} and {@link #remove()} operations perform
-+ * in logarithmic time.  The {@link #get()} operation performs in constant
-+ * time.  All other operations perform in linear time or worse.
-+ * <p/>
-+ * Note that this implementation is not synchronized.  Use
-+ * {@link org.apache.commons.collections15.BufferUtils#synchronizedBuffer(Buffer)} or
-+ * {@link org.apache.commons.collections15.buffer.SynchronizedBuffer#decorate(Buffer)}
-+ * to provide synchronized access to a <code>PriorityBuffer</code>:
-+ * <p/>
-+ * <pre>
-+ * Buffer heap = SynchronizedBuffer.decorate(new PriorityBuffer());
-+ * </pre>
-+ *
-+ * @author Peter Donald
-+ * @author Ram Chidambaram
-+ * @author Michael A. Smith
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0 (previously BinaryHeap v1.0)
-+ */
-+public class PriorityBuffer <E> extends AbstractCollection<E> implements Buffer<E> {
-+
-+    /**
-+     * The default capacity for the buffer.
-+     */
-+    private static final int DEFAULT_CAPACITY = 13;
-+
-+    /**
-+     * The elements in this buffer.
-+     */
-+    protected E[] elements;
-+    /**
-+     * The number of elements currently in this buffer.
-+     */
-+    protected int size;
-+    /**
-+     * If true, the first element as determined by the sort order will
-+     * be returned.  If false, the last element as determined by the
-+     * sort order will be returned.
-+     */
-+    protected boolean ascendingOrder;
-+    /**
-+     * The comparator used to order the elements
-+     */
-+    protected Comparator<? super E> comparator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new empty buffer that sorts in ascending order by the
-+     * natural order of the objects added.
-+     */
-+    public PriorityBuffer() {
-+        this(DEFAULT_CAPACITY, true, null);
-+    }
-+
-+    /**
-+     * Constructs a new empty buffer that sorts in ascending order using the
-+     * specified comparator.
-+     *
-+     * @param comparator the comparator used to order the elements,
-+     *                   null means use natural order
-+     */
-+    public PriorityBuffer(Comparator<? super E> comparator) {
-+        this(DEFAULT_CAPACITY, true, comparator);
-+    }
-+
-+    /**
-+     * Constructs a new empty buffer specifying the sort order and using the
-+     * natural order of the objects added.
-+     *
-+     * @param ascendingOrder if <code>true</code> the heap is created as a
-+     *                       minimum heap; otherwise, the heap is created as a maximum heap
-+     */
-+    public PriorityBuffer(boolean ascendingOrder) {
-+        this(DEFAULT_CAPACITY, ascendingOrder, null);
-+    }
-+
-+    /**
-+     * Constructs a new empty buffer specifying the sort order and comparator.
-+     *
-+     * @param ascendingOrder true to use the order imposed by the given
-+     *                       comparator; false to reverse that order
-+     * @param comparator     the comparator used to order the elements,
-+     *                       null means use natural order
-+     */
-+    public PriorityBuffer(boolean ascendingOrder, Comparator<? super E> comparator) {
-+        this(DEFAULT_CAPACITY, ascendingOrder, comparator);
-+    }
-+
-+    /**
-+     * Constructs a new empty buffer that sorts in ascending order by the
-+     * natural order of the objects added, specifying an initial capacity.
-+     *
-+     * @param capacity the initial capacity for the buffer, greater than zero
-+     * @throws IllegalArgumentException if <code>capacity</code> is <= <code>0</code>
-+     */
-+    public PriorityBuffer(int capacity) {
-+        this(capacity, true, null);
-+    }
-+
-+    /**
-+     * Constructs a new empty buffer that sorts in ascending order using the
-+     * specified comparator and initial capacity.
-+     *
-+     * @param capacity   the initial capacity for the buffer, greater than zero
-+     * @param comparator the comparator used to order the elements,
-+     *                   null means use natural order
-+     * @throws IllegalArgumentException if <code>capacity</code> is <= <code>0</code>
-+     */
-+    public PriorityBuffer(int capacity, Comparator<? super E> comparator) {
-+        this(capacity, true, comparator);
-+    }
-+
-+    /**
-+     * Constructs a new empty buffer that specifying initial capacity and
-+     * sort order, using the natural order of the objects added.
-+     *
-+     * @param capacity       the initial capacity for the buffer, greater than zero
-+     * @param ascendingOrder if <code>true</code> the heap is created as a
-+     *                       minimum heap; otherwise, the heap is created as a maximum heap.
-+     * @throws IllegalArgumentException if <code>capacity</code> is <code><= 0</code>
-+     */
-+    public PriorityBuffer(int capacity, boolean ascendingOrder) {
-+        this(capacity, ascendingOrder, null);
-+    }
-+
-+    /**
-+     * Constructs a new empty buffer that specifying initial capacity,
-+     * sort order and comparator.
-+     *
-+     * @param capacity       the initial capacity for the buffer, greater than zero
-+     * @param ascendingOrder true to use the order imposed by the given
-+     *                       comparator; false to reverse that order
-+     * @param comparator     the comparator used to order the elements,
-+     *                       null means use natural order
-+     * @throws IllegalArgumentException if <code>capacity</code> is <code><= 0</code>
-+     */
-+    public PriorityBuffer(int capacity, boolean ascendingOrder, Comparator<? super E> comparator) {
-+        super();
-+        if (capacity <= 0) {
-+            throw new IllegalArgumentException("invalid capacity");
-+        }
-+        this.ascendingOrder = ascendingOrder;
-+
-+        //+1 as 0 is noop
-+        this.elements = (E[]) new Object[capacity + 1];
-+        this.comparator = comparator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks whether the heap is ascending or descending order.
-+     *
-+     * @return true if ascending order (a min heap)
-+     */
-+    public boolean isAscendingOrder() {
-+        return ascendingOrder;
-+    }
-+
-+    /**
-+     * Gets the comparator being used for this buffer, null is natural order.
-+     *
-+     * @return the comparator in use, null is natural order
-+     */
-+    public Comparator<? super E> comparator() {
-+        return comparator;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the number of elements in this buffer.
-+     *
-+     * @return the number of elements in this buffer
-+     */
-+    public int size() {
-+        return size;
-+    }
-+
-+    /**
-+     * Clears all elements from the buffer.
-+     */
-+    public void clear() {
-+        elements = (E[]) new Object[elements.length]; // for gc
-+        size = 0;
-+    }
-+
-+    /**
-+     * Adds an element to the buffer.
-+     * <p/>
-+     * The element added will be sorted according to the comparator in use.
-+     *
-+     * @param element the element to be added
-+     * @return true always
-+     */
-+    public boolean add(E element) {
-+        if (isAtCapacity()) {
-+            grow();
-+        }
-+        // percolate element to it's place in tree
-+        if (ascendingOrder) {
-+            percolateUpMinHeap(element);
-+        } else {
-+            percolateUpMaxHeap(element);
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Gets the next element to be removed without actually removing it (peek).
-+     *
-+     * @return the next element
-+     * @throws BufferUnderflowException if the buffer is empty
-+     */
-+    public E get() {
-+        if (isEmpty()) {
-+            throw new BufferUnderflowException();
-+        } else {
-+            return elements[1];
-+        }
-+    }
-+
-+    /**
-+     * Gets and removes the next element (pop).
-+     *
-+     * @return the next element
-+     * @throws BufferUnderflowException if the buffer is empty
-+     */
-+    public E remove() {
-+        final E result = get();
-+        elements[1] = elements[size--];
-+
-+        // set the unused element to 'null' so that the garbage collector
-+        // can free the object if not used anywhere else.(remove reference)
-+        elements[size + 1] = null;
-+
-+        if (size != 0) {
-+            // percolate top element to it's place in tree
-+            if (ascendingOrder) {
-+                percolateDownMinHeap(1);
-+            } else {
-+                percolateDownMaxHeap(1);
-+            }
-+        }
-+
-+        return result;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Tests if the buffer is at capacity.
-+     *
-+     * @return <code>true</code> if buffer is full; <code>false</code> otherwise.
-+     */
-+    protected boolean isAtCapacity() {
-+        //+1 as element 0 is noop
-+        return elements.length == size + 1;
-+    }
-+
-+
-+    /**
-+     * Percolates element down heap from the position given by the index.
-+     * <p/>
-+     * Assumes it is a minimum heap.
-+     *
-+     * @param index the index for the element
-+     */
-+    protected void percolateDownMinHeap(final int index) {
-+        final E element = elements[index];
-+        int hole = index;
-+
-+        while ((hole * 2) <= size) {
-+            int child = hole * 2;
-+
-+            // if we have a right child and that child can not be percolated
-+            // up then move onto other child
-+            if (child != size && compare(elements[child + 1], elements[child]) < 0) {
-+                child++;
-+            }
-+
-+            // if we found resting place of bubble then terminate search
-+            if (compare(elements[child], element) >= 0) {
-+                break;
-+            }
-+
-+            elements[hole] = elements[child];
-+            hole = child;
-+        }
-+
-+        elements[hole] = element;
-+    }
-+
-+    /**
-+     * Percolates element down heap from the position given by the index.
-+     * <p/>
-+     * Assumes it is a maximum heap.
-+     *
-+     * @param index the index of the element
-+     */
-+    protected void percolateDownMaxHeap(final int index) {
-+        final E element = elements[index];
-+        int hole = index;
-+
-+        while ((hole * 2) <= size) {
-+            int child = hole * 2;
-+
-+            // if we have a right child and that child can not be percolated
-+            // up then move onto other child
-+            if (child != size && compare(elements[child + 1], elements[child]) > 0) {
-+                child++;
-+            }
-+
-+            // if we found resting place of bubble then terminate search
-+            if (compare(elements[child], element) <= 0) {
-+                break;
-+            }
-+
-+            elements[hole] = elements[child];
-+            hole = child;
-+        }
-+
-+        elements[hole] = element;
-+    }
-+
-+    /**
-+     * Percolates element up heap from the position given by the index.
-+     * <p/>
-+     * Assumes it is a minimum heap.
-+     *
-+     * @param index the index of the element to be percolated up
-+     */
-+    protected void percolateUpMinHeap(final int index) {
-+        int hole = index;
-+        E element = elements[hole];
-+        while (hole > 1 && compare(element, elements[hole / 2]) < 0) {
-+            // save element that is being pushed down
-+            // as the element "bubble" is percolated up
-+            final int next = hole / 2;
-+            elements[hole] = elements[next];
-+            hole = next;
-+        }
-+        elements[hole] = element;
-+    }
-+
-+    /**
-+     * Percolates a new element up heap from the bottom.
-+     * <p/>
-+     * Assumes it is a minimum heap.
-+     *
-+     * @param element the element
-+     */
-+    protected void percolateUpMinHeap(final E element) {
-+        elements[++size] = element;
-+        percolateUpMinHeap(size);
-+    }
-+
-+    /**
-+     * Percolates element up heap from from the position given by the index.
-+     * <p/>
-+     * Assume it is a maximum heap.
-+     *
-+     * @param index the index of the element to be percolated up
-+     */
-+    protected void percolateUpMaxHeap(final int index) {
-+        int hole = index;
-+        E element = elements[hole];
-+
-+        while (hole > 1 && compare(element, elements[hole / 2]) > 0) {
-+            // save element that is being pushed down
-+            // as the element "bubble" is percolated up
-+            final int next = hole / 2;
-+            elements[hole] = elements[next];
-+            hole = next;
-+        }
-+
-+        elements[hole] = element;
-+    }
-+
-+    /**
-+     * Percolates a new element up heap from the bottom.
-+     * <p/>
-+     * Assume it is a maximum heap.
-+     *
-+     * @param element the element
-+     */
-+    protected void percolateUpMaxHeap(final E element) {
-+        elements[++size] = element;
-+        percolateUpMaxHeap(size);
-+    }
-+
-+    /**
-+     * Compares two objects using the comparator if specified, or the
-+     * natural order otherwise.
-+     *
-+     * @param a the first object
-+     * @param b the second object
-+     * @return -ve if a less than b, 0 if they are equal, +ve if a greater than b
-+     */
-+    protected int compare(E a, E b) {
-+        if (comparator != null) {
-+            return comparator.compare(a, b);
-+        } else {
-+            return ((Comparable) a).compareTo(b);
-+        }
-+    }
-+
-+    /**
-+     * Increases the size of the heap to support additional elements
-+     */
-+    protected void grow() {
-+        final E[] array = (E[]) new Object[elements.length * 2];
-+        System.arraycopy(elements, 0, array, 0, elements.length);
-+        elements = array;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns an iterator over this heap's elements.
-+     *
-+     * @return an iterator over this heap's elements
-+     */
-+    public Iterator<E> iterator() {
-+        return new Iterator<E>() {
-+
-+            private int index = 1;
-+            private int lastReturnedIndex = -1;
-+
-+            public boolean hasNext() {
-+                return index <= size;
-+            }
-+
-+            public E next() {
-+                if (!hasNext()) {
-+                    throw new NoSuchElementException();
-+                }
-+                lastReturnedIndex = index;
-+                index++;
-+                return elements[lastReturnedIndex];
-+            }
-+
-+            public void remove() {
-+                if (lastReturnedIndex == -1) {
-+                    throw new IllegalStateException();
-+                }
-+                elements[lastReturnedIndex] = elements[size];
-+                elements[size] = null;
-+                size--;
-+                if (size != 0 && lastReturnedIndex <= size) {
-+                    int compareToParent = 0;
-+                    if (lastReturnedIndex > 1) {
-+                        compareToParent = compare(elements[lastReturnedIndex], elements[lastReturnedIndex / 2]);
-+                    }
-+                    if (ascendingOrder) {
-+                        if (lastReturnedIndex > 1 && compareToParent < 0) {
-+                            percolateUpMinHeap(lastReturnedIndex);
-+                        } else {
-+                            percolateDownMinHeap(lastReturnedIndex);
-+                        }
-+                    } else {  // max heap
-+                        if (lastReturnedIndex > 1 && compareToParent > 0) {
-+                            percolateUpMaxHeap(lastReturnedIndex);
-+                        } else {
-+                            percolateDownMaxHeap(lastReturnedIndex);
-+                        }
-+                    }
-+                }
-+                index--;
-+                lastReturnedIndex = -1;
-+            }
-+
-+        };
-+    }
-+
-+    /**
-+     * Returns a string representation of this heap.  The returned string
-+     * is similar to those produced by standard JDK collections15.
-+     *
-+     * @return a string representation of this heap
-+     */
-+    public String toString() {
-+        final StringBuffer sb = new StringBuffer();
-+
-+        sb.append("[ ");
-+
-+        for (int i = 1; i < size + 1; i++) {
-+            if (i != 1) {
-+                sb.append(", ");
-+            }
-+            sb.append(elements[i]);
-+        }
-+
-+        sb.append(" ]");
-+
-+        return sb.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/SynchronizedBuffer.java
-@@ -0,0 +1,96 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.collection.SynchronizedCollection;
-+
-+/**
-+ * Decorates another <code>Buffer</code> to synchronize its behaviour
-+ * for a multi-threaded environment.
-+ * <p/>
-+ * Methods are synchronized, then forwarded to the decorated buffer.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SynchronizedBuffer <E> extends SynchronizedCollection<E> implements Buffer<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -6859936183953626253L;
-+
-+    /**
-+     * Factory method to create a synchronized buffer.
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @return a new synchronized Buffer
-+     * @throws IllegalArgumentException if buffer is null
-+     */
-+    public static <E> Buffer<E> decorate(Buffer<E> buffer) {
-+        return new SynchronizedBuffer(buffer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @throws IllegalArgumentException if the buffer is null
-+     */
-+    protected SynchronizedBuffer(Buffer<E> buffer) {
-+        super(buffer);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @param lock   the lock object to use, must not be null
-+     * @throws IllegalArgumentException if the buffer is null
-+     */
-+    protected SynchronizedBuffer(Buffer<E> buffer, Object lock) {
-+        super(buffer, lock);
-+    }
-+
-+    /**
-+     * Gets the buffer being decorated.
-+     *
-+     * @return the decorated buffer
-+     */
-+    protected Buffer<E> getBuffer() {
-+        return (Buffer<E>) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E get() {
-+        synchronized (lock) {
-+            return getBuffer().get();
-+        }
-+    }
-+
-+    public E remove() {
-+        synchronized (lock) {
-+            return getBuffer().remove();
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/TransformedBuffer.java
-@@ -0,0 +1,94 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.Transformer;
-+import org.apache.commons.collections15.collection.TransformedCollection;
-+
-+/**
-+ * Decorates another <code>Buffer</code> to transform objects that are added.
-+ * <p/>
-+ * The add methods are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Collection contract.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedBuffer <I,O> extends TransformedCollection<I, O> implements Buffer {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -7901091318986132033L;
-+
-+    /**
-+     * Factory method to create a transforming buffer.
-+     * <p/>
-+     * If there are any elements already in the buffer being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param buffer      the buffer to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @return a new transformed Buffer
-+     * @throws IllegalArgumentException if buffer or transformer is null
-+     */
-+    public static <I,O> Buffer<O> decorate(Buffer<I> buffer, Transformer<? super I, ? extends O> transformer) {
-+        return new TransformedBuffer<I, O>(buffer, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the buffer being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param buffer      the buffer to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if buffer or transformer is null
-+     */
-+    protected TransformedBuffer(Buffer<I> buffer, Transformer<? super I, ? extends O> transformer) {
-+        super(buffer, transformer);
-+    }
-+
-+    /**
-+     * Gets the decorated buffer.
-+     *
-+     * @return the decorated buffer
-+     */
-+    protected Buffer<O> getBuffer() {
-+        return (Buffer<O>) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Object get() {
-+        return getBuffer().get();
-+    }
-+
-+    public Object remove() {
-+        return getBuffer().remove();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/TypedBuffer.java
-@@ -0,0 +1,60 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+/**
-+ * Decorates another <code>Buffer</code> to validate that elements added
-+ * are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @author Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TypedBuffer <E> {
-+
-+    /**
-+     * Factory method to create a typed list.
-+     * <p/>
-+     * If there are any elements already in the buffer being decorated, they
-+     * are validated.
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @param type   the type to allow into the buffer, must not be null
-+     * @return a new typed Buffer
-+     * @throws IllegalArgumentException if buffer or type is null
-+     * @throws IllegalArgumentException if the buffer contains invalid elements
-+     */
-+    public static <E> Buffer<E> decorate(Buffer<E> buffer, Class type) {
-+        return new PredicatedBuffer<E>(buffer, InstanceofPredicate.getInstance(type));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedBuffer() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/UnboundedFifoBuffer.java
-@@ -0,0 +1,334 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.BufferUnderflowException;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.AbstractCollection;
-+import java.util.Iterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * UnboundedFifoBuffer is a very efficient buffer implementation.
-+ * According to performance testing, it exhibits a constant access time, but it
-+ * also outperforms ArrayList when used for the same purpose.
-+ * <p/>
-+ * The removal order of an <code>UnboundedFifoBuffer</code> is based on the insertion
-+ * order; elements are removed in the same order in which they were added.
-+ * The iteration order is the same as the removal order.
-+ * <p/>
-+ * The {@link #remove()} and {@link #get()} operations perform in constant time.
-+ * The {@link #add(Object)} operation performs in amortized constant time.  All
-+ * other operations perform in linear time or worse.
-+ * <p/>
-+ * Note that this implementation is not synchronized.  The following can be
-+ * used to provide synchronized access to your <code>UnboundedFifoBuffer</code>:
-+ * <pre>
-+ *   Buffer fifo = BufferUtils.synchronizedBuffer(new UnboundedFifoBuffer());
-+ * </pre>
-+ * <p/>
-+ * This buffer prevents null objects from being added.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Avalon
-+ * @author Federico Barbieri
-+ * @author Berin Loritsch
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0 (previously in main package v2.1)
-+ */
-+public class UnboundedFifoBuffer <E> extends AbstractCollection<E> implements Buffer<E>, Serializable {
-+
-+    /**
-+     * Serialization vesrion
-+     */
-+    private static final long serialVersionUID = -3482960336579541419L;
-+
-+    /**
-+     * The array of objects in the buffer.
-+     */
-+    protected transient E[] buffer;
-+    /**
-+     * The current head index.
-+     */
-+    protected transient int head;
-+    /**
-+     * The current tail index.
-+     */
-+    protected transient int tail;
-+
-+    /**
-+     * Constructs an UnboundedFifoBuffer with the default number of elements.
-+     * It is exactly the same as performing the following:
-+     * <p/>
-+     * <pre>
-+     *   new UnboundedFifoBuffer(32);
-+     * </pre>
-+     */
-+    public UnboundedFifoBuffer() {
-+        this(32);
-+    }
-+
-+    /**
-+     * Constructs an UnboundedFifoBuffer with the specified number of elements.
-+     * The integer must be a positive integer.
-+     *
-+     * @param initialSize the initial size of the buffer
-+     * @throws IllegalArgumentException if the size is less than 1
-+     */
-+    public UnboundedFifoBuffer(int initialSize) {
-+        if (initialSize <= 0) {
-+            throw new IllegalArgumentException("The size must be greater than 0");
-+        }
-+        buffer = (E[]) new Object[initialSize + 1];
-+        head = 0;
-+        tail = 0;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the buffer out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeInt(size());
-+        for (Iterator it = iterator(); it.hasNext();) {
-+            out.writeObject(it.next());
-+        }
-+    }
-+
-+    /**
-+     * Read the buffer in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        int size = in.readInt();
-+        buffer = (E[]) new Object[size];
-+        for (int i = 0; i < size; i++) {
-+            buffer[i] = (E) in.readObject();
-+        }
-+        head = 0;
-+        tail = size;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the number of elements stored in the buffer.
-+     *
-+     * @return this buffer's size
-+     */
-+    public int size() {
-+        int size = 0;
-+
-+        if (tail < head) {
-+            size = buffer.length - head + tail;
-+        } else {
-+            size = tail - head;
-+        }
-+
-+        return size;
-+    }
-+
-+    /**
-+     * Returns true if this buffer is empty; false otherwise.
-+     *
-+     * @return true if this buffer is empty
-+     */
-+    public boolean isEmpty() {
-+        return (size() == 0);
-+    }
-+
-+    /**
-+     * Adds the given element to this buffer.
-+     *
-+     * @param obj the element to add
-+     * @return true, always
-+     * @throws NullPointerException if the given element is null
-+     */
-+    public boolean add(final E obj) {
-+        if (obj == null) {
-+            throw new NullPointerException("Attempted to add null object to buffer");
-+        }
-+
-+        if (size() + 1 >= buffer.length) {
-+            E[] tmp = (E[]) new Object[((buffer.length - 1) * 2) + 1];
-+
-+            int j = 0;
-+            for (int i = head; i != tail;) {
-+                tmp[j] = buffer[i];
-+                buffer[i] = null;
-+
-+                j++;
-+                i++;
-+                if (i == buffer.length) {
-+                    i = 0;
-+                }
-+            }
-+
-+            buffer = tmp;
-+            head = 0;
-+            tail = j;
-+        }
-+
-+        buffer[tail] = obj;
-+        tail++;
-+        if (tail >= buffer.length) {
-+            tail = 0;
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Returns the next object in the buffer.
-+     *
-+     * @return the next object in the buffer
-+     * @throws BufferUnderflowException if this buffer is empty
-+     */
-+    public E get() {
-+        if (isEmpty()) {
-+            throw new BufferUnderflowException("The buffer is already empty");
-+        }
-+
-+        return buffer[head];
-+    }
-+
-+    /**
-+     * Removes the next object from the buffer
-+     *
-+     * @return the removed object
-+     * @throws BufferUnderflowException if this buffer is empty
-+     */
-+    public E remove() {
-+        if (isEmpty()) {
-+            throw new BufferUnderflowException("The buffer is already empty");
-+        }
-+
-+        E element = buffer[head];
-+
-+        if (null != element) {
-+            buffer[head] = null;
-+
-+            head++;
-+            if (head >= buffer.length) {
-+                head = 0;
-+            }
-+        }
-+
-+        return element;
-+    }
-+
-+    /**
-+     * Increments the internal index.
-+     *
-+     * @param index the index to increment
-+     * @return the updated index
-+     */
-+    private int increment(int index) {
-+        index++;
-+        if (index >= buffer.length) {
-+            index = 0;
-+        }
-+        return index;
-+    }
-+
-+    /**
-+     * Decrements the internal index.
-+     *
-+     * @param index the index to decrement
-+     * @return the updated index
-+     */
-+    private int decrement(int index) {
-+        index--;
-+        if (index < 0) {
-+            index = buffer.length - 1;
-+        }
-+        return index;
-+    }
-+
-+    /**
-+     * Returns an iterator over this buffer's elements.
-+     *
-+     * @return an iterator over this buffer's elements
-+     */
-+    public Iterator<E> iterator() {
-+        return new Iterator<E>() {
-+
-+            private int index = head;
-+            private int lastReturnedIndex = -1;
-+
-+            public boolean hasNext() {
-+                return index != tail;
-+
-+            }
-+
-+            public E next() {
-+                if (!hasNext()) {
-+                    throw new NoSuchElementException();
-+                }
-+                lastReturnedIndex = index;
-+                index = increment(index);
-+                return buffer[lastReturnedIndex];
-+            }
-+
-+            public void remove() {
-+                if (lastReturnedIndex == -1) {
-+                    throw new IllegalStateException();
-+                }
-+
-+                // First element can be removed quickly
-+                if (lastReturnedIndex == head) {
-+                    UnboundedFifoBuffer.this.remove();
-+                    lastReturnedIndex = -1;
-+                    return;
-+                }
-+
-+                // Other elements require us to shift the subsequent elements
-+                int i = lastReturnedIndex + 1;
-+                while (i != tail) {
-+                    if (i >= buffer.length) {
-+                        buffer[i - 1] = buffer[0];
-+                        i = 0;
-+                    } else {
-+                        buffer[i - 1] = buffer[i];
-+                        i++;
-+                    }
-+                }
-+
-+                lastReturnedIndex = -1;
-+                tail = decrement(tail);
-+                buffer[tail] = null;
-+                index = decrement(index);
-+            }
-+
-+        };
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/UnmodifiableBuffer.java
-@@ -0,0 +1,131 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.buffer;
-+
-+import org.apache.commons.collections15.Buffer;
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates another <code>Buffer</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableBuffer <E> extends AbstractBufferDecorator<E> implements Unmodifiable, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 1832948656215393357L;
-+
-+    /**
-+     * Factory method to create an unmodifiable buffer.
-+     * <p/>
-+     * If the buffer passed in is already unmodifiable, it is returned.
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @return an unmodifiable Buffer
-+     * @throws IllegalArgumentException if buffer is null
-+     */
-+    public static <E> Buffer<E> decorate(Buffer<E> buffer) {
-+        if (buffer instanceof Unmodifiable) {
-+            return buffer;
-+        }
-+        return new UnmodifiableBuffer<E>(buffer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param buffer the buffer to decorate, must not be null
-+     * @throws IllegalArgumentException if buffer is null
-+     */
-+    private UnmodifiableBuffer(Buffer<E> buffer) {
-+        super(buffer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the collection out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(collection);
-+    }
-+
-+    /**
-+     * Read the collection in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        collection = (Collection<E>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E remove() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/buffer/package.html
-@@ -0,0 +1,40 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:20 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link org.apache.commons.collections.Buffer Buffer} interface.
-+<p>
-+The following implementations are provided in the package:
-+<ul>
-+<li>PriorityBuffer - provides for removal based on a comparator ordering
-+<li>BoundedFifoBuffer - implements a buffer with a fixed size that throws exceptions when full
-+<li>CircularFifoBuffer - implements a buffer with a fixed size that discards oldest when full
-+<li>UnboundedFifoBuffer - implements a buffer that grows in size if necessary
-+</ul>
-+<p>
-+The following decorators are provided in the package:
-+<ul>
-+<li>Synchronized - synchronizes method access for multi-threaded environments
-+<li>Unmodifiable - ensures the collection cannot be altered
-+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
-+<li>Typed - ensures that only elements that are of a specific type can be added
-+<li>Transformed - transforms elements added to the buffer
-+<li>Blocking - blocks on get and remove until an element is available
-+</ul>
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/AbstractCollectionDecorator.java
-@@ -0,0 +1,148 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates another <code>Collection</code> to provide additional behaviour.
-+ * <p/>
-+ * Each method call made on this <code>Collection</code> is forwarded to the
-+ * decorated <code>Collection</code>. This class is used as a framework on which
-+ * to build to extensions such as synchronized and unmodifiable behaviour. The
-+ * main advantage of decoration is that one decorator can wrap any implementation
-+ * of <code>Collection</code>, whereas sub-classing requires a new class to be
-+ * written for each implementation.
-+ * <p/>
-+ * This implementation does not perform any special processing with
-+ * {@link #iterator()}. Instead it simply returns the value from the
-+ * wrapped collection. This may be undesirable, for example if you are trying
-+ * to write an unmodifiable implementation it might provide a loophole.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractCollectionDecorator <E> implements Collection<E> {
-+
-+    /**
-+     * The collection being decorated
-+     */
-+    protected Collection<E> collection;
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractCollectionDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param coll the collection to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    protected AbstractCollectionDecorator(Collection<E> coll) {
-+        if (coll == null) {
-+            throw new IllegalArgumentException("Collection must not be null");
-+        }
-+        this.collection = coll;
-+    }
-+
-+    /**
-+     * Gets the collection being decorated.
-+     *
-+     * @return the decorated collection
-+     */
-+    protected Collection<E> getCollection() {
-+        return collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E object) {
-+        return collection.add(object);
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        return collection.addAll(coll);
-+    }
-+
-+    public void clear() {
-+        collection.clear();
-+    }
-+
-+    public boolean contains(Object object) {
-+        return collection.contains(object);
-+    }
-+
-+    public boolean isEmpty() {
-+        return collection.isEmpty();
-+    }
-+
-+    public Iterator<E> iterator() {
-+        return collection.iterator();
-+    }
-+
-+    public boolean remove(Object object) {
-+        return collection.remove(object);
-+    }
-+
-+    public int size() {
-+        return collection.size();
-+    }
-+
-+    public Object[] toArray() {
-+        return (Object[]) collection.toArray();
-+    }
-+
-+    public <T> T[] toArray(T[] object) {
-+        return (T[]) collection.toArray(object);
-+    }
-+
-+    public boolean containsAll(Collection<?> coll) {
-+        return collection.containsAll(coll);
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        return collection.removeAll(coll);
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        return collection.retainAll(coll);
-+    }
-+
-+    public boolean equals(Object object) {
-+        if (object == this) {
-+            return true;
-+        }
-+        return collection.equals(object);
-+    }
-+
-+    public int hashCode() {
-+        return collection.hashCode();
-+    }
-+
-+    public String toString() {
-+        return collection.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/AbstractSerializableCollectionDecorator.java
-@@ -0,0 +1,69 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+
-+/**
-+ * Serializable subclass of AbstractCollectionDecorator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @since Commons Collections 3.1
-+ */
-+public abstract class AbstractSerializableCollectionDecorator <E> extends AbstractCollectionDecorator<E> implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 6249888059822088500L;
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected AbstractSerializableCollectionDecorator(Collection<E> coll) {
-+        super(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the collection out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(collection);
-+    }
-+
-+    /**
-+     * Read the collection in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        collection = (Collection<E>) in.readObject();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/CompositeCollection.java
-@@ -0,0 +1,444 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import org.apache.commons.collections15.iterators.EmptyIterator;
-+import org.apache.commons.collections15.iterators.IteratorChain;
-+import org.apache.commons.collections15.list.UnmodifiableList;
-+
-+import java.lang.reflect.Array;
-+import java.util.ArrayList;
-+import java.util.Arrays;
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates a collection of other collections15 to provide a single unified view.
-+ * <p/>
-+ * Changes made to this collection will actually be made on the decorated collection.
-+ * Add and remove operations require the use of a pluggable strategy. If no
-+ * strategy is provided then add and remove are unsupported.
-+ *
-+ * @author Brian McCallister
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Phil Steitz
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class CompositeCollection <E> implements Collection<E> {
-+
-+    /**
-+     * CollectionMutator to handle changes to the collection
-+     */
-+    protected CollectionMutator<E> mutator;
-+
-+    /**
-+     * Collections in the composite
-+     */
-+    protected Collection<E>[] all;
-+
-+    /**
-+     * Create an empty CompositeCollection.
-+     */
-+    public CompositeCollection() {
-+        super();
-+        this.all = new Collection[0];
-+    }
-+
-+    /**
-+     * Create a Composite Collection with only coll composited.
-+     *
-+     * @param coll a collection to decorate
-+     */
-+    public CompositeCollection(Collection<E> coll) {
-+        this();
-+        this.addComposited(coll);
-+    }
-+
-+    /**
-+     * Create a CompositeCollection with colls as the initial list of
-+     * composited collections15.
-+     *
-+     * @param colls a variable number of collections15 to decorate
-+     */
-+    public CompositeCollection(Collection<E>... colls) {
-+        this();
-+        this.addComposited(colls);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the size of this composite collection.
-+     * <p/>
-+     * This implementation calls <code>size()</code> on each collection.
-+     *
-+     * @return total number of elements in all contained containers
-+     */
-+    public int size() {
-+        int size = 0;
-+        for (int i = this.all.length - 1; i >= 0; i--) {
-+            size += this.all[i].size();
-+        }
-+        return size;
-+    }
-+
-+    /**
-+     * Checks whether this composite collection is empty.
-+     * <p/>
-+     * This implementation calls <code>isEmpty()</code> on each collection.
-+     *
-+     * @return true if all of the contained collections15 are empty
-+     */
-+    public boolean isEmpty() {
-+        for (int i = this.all.length - 1; i >= 0; i--) {
-+            if (this.all[i].isEmpty() == false) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Checks whether this composite collection contains the object.
-+     * <p/>
-+     * This implementation calls <code>contains()</code> on each collection.
-+     *
-+     * @param obj the object to search for
-+     * @return true if obj is contained in any of the contained collections15
-+     */
-+    public boolean contains(Object obj) {
-+        for (int i = this.all.length - 1; i >= 0; i--) {
-+            if (this.all[i].contains(obj)) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Gets an iterator over all the collections15 in this composite.
-+     * <p/>
-+     * This implementation uses an <code>IteratorChain</code>.
-+     *
-+     * @return an <code>IteratorChain</code> instance which supports
-+     *         <code>remove()</code>. Iteration occurs over contained collections15 in
-+     *         the order they were added, but this behavior should not be relied upon.
-+     * @see IteratorChain
-+     */
-+    public Iterator<E> iterator() {
-+        if (this.all.length == 0) {
-+            return EmptyIterator.INSTANCE;
-+        }
-+        IteratorChain<E> chain = new IteratorChain<E>();
-+        for (int i = 0; i < this.all.length; ++i) {
-+            chain.addIterator(this.all[i].iterator());
-+        }
-+        return chain;
-+    }
-+
-+    /**
-+     * Returns an array containing all of the elements in this composite.
-+     *
-+     * @return an object array of all the elements in the collection
-+     */
-+    public E[] toArray() {
-+        final E[] result = (E[]) new Object[this.size()];
-+        int i = 0;
-+        for (Iterator<E> it = this.iterator(); it.hasNext(); i++) {
-+            result[i] = (E) it.next();
-+        }
-+        return result;
-+    }
-+
-+    /**
-+     * Returns an object array, populating the supplied array if possible.
-+     * See <code>Collection</code> interface for full details.
-+     *
-+     * @param array the array to use, populating if possible
-+     * @return an array of all the elements in the collection
-+     */
-+
-+    public <E> E[] toArray(E[] array) {
-+        int size = this.size();
-+        E[] result = null;
-+        if (array.length >= size) {
-+            result = array;
-+        } else {
-+            result = (E[]) Array.newInstance(array.getClass().getComponentType(), size);
-+        }
-+
-+        int offset = 0;
-+        for (int i = 0; i < this.all.length; ++i) {
-+            for (Iterator it = this.all[i].iterator(); it.hasNext();) {
-+                result[offset++] = (E) it.next();
-+            }
-+        }
-+        if (result.length > size) {
-+            result[size] = null;
-+        }
-+        return result;
-+    }
-+
-+    /**
-+     * Adds an object to the collection, throwing UnsupportedOperationException
-+     * unless a CollectionMutator strategy is specified.
-+     *
-+     * @param obj the object to add
-+     * @return true if the collection was modified
-+     * @throws UnsupportedOperationException if CollectionMutator hasn't been set
-+     * @throws UnsupportedOperationException if add is unsupported
-+     * @throws ClassCastException            if the object cannot be added due to its type
-+     * @throws NullPointerException          if the object cannot be added because its null
-+     * @throws IllegalArgumentException      if the object cannot be added
-+     */
-+    public boolean add(E obj) {
-+        if (this.mutator == null) {
-+            throw new UnsupportedOperationException("add() is not supported on CompositeCollection without a CollectionMutator strategy");
-+        }
-+        return this.mutator.add(this, this.all, obj);
-+    }
-+
-+    /**
-+     * Removes an object from the collection, throwing UnsupportedOperationException
-+     * unless a CollectionMutator strategy is specified.
-+     *
-+     * @param obj the object being removed
-+     * @return true if the collection is changed
-+     * @throws UnsupportedOperationException if removed is unsupported
-+     * @throws ClassCastException            if the object cannot be removed due to its type
-+     * @throws NullPointerException          if the object cannot be removed because its null
-+     * @throws IllegalArgumentException      if the object cannot be removed
-+     */
-+    public boolean remove(Object obj) {
-+        if (this.mutator == null) {
-+            throw new UnsupportedOperationException("remove() is not supported on CompositeCollection without a CollectionMutator strategy");
-+        }
-+        return this.mutator.remove(this, this.all, obj);
-+    }
-+
-+    /**
-+     * Checks whether this composite contains all the elements in the specified collection.
-+     * <p/>
-+     * This implementation calls <code>contains()</code> for each element in the
-+     * specified collection.
-+     *
-+     * @param coll the collection to check for
-+     * @return true if all elements contained
-+     */
-+    public boolean containsAll(Collection<?> coll) {
-+        for (Iterator it = coll.iterator(); it.hasNext();) {
-+            if (this.contains(it.next()) == false) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Adds a collection of elements to this collection, throwing
-+     * UnsupportedOperationException unless a CollectionMutator strategy is specified.
-+     *
-+     * @param coll the collection to add
-+     * @return true if the collection was modified
-+     * @throws UnsupportedOperationException if CollectionMutator hasn't been set
-+     * @throws UnsupportedOperationException if add is unsupported
-+     * @throws ClassCastException            if the object cannot be added due to its type
-+     * @throws NullPointerException          if the object cannot be added because its null
-+     * @throws IllegalArgumentException      if the object cannot be added
-+     */
-+    public boolean addAll(Collection<? extends E> coll) {
-+        if (this.mutator == null) {
-+            throw new UnsupportedOperationException("addAll() is not supported on CompositeCollection without a CollectionMutator strategy");
-+        }
-+        return this.mutator.addAll(this, this.all, coll);
-+    }
-+
-+    /**
-+     * Removes the elements in the specified collection from this composite collection.
-+     * <p/>
-+     * This implementation calls <code>removeAll</code> on each collection.
-+     *
-+     * @param coll the collection to remove
-+     * @return true if the collection was modified
-+     * @throws UnsupportedOperationException if removeAll is unsupported
-+     */
-+    public boolean removeAll(Collection<?> coll) {
-+        if (coll.size() == 0) {
-+            return false;
-+        }
-+        boolean changed = false;
-+        for (int i = this.all.length - 1; i >= 0; i--) {
-+            changed = (this.all[i].removeAll(coll) || changed);
-+        }
-+        return changed;
-+    }
-+
-+    /**
-+     * Retains all the elements in the specified collection in this composite collection,
-+     * removing all others.
-+     * <p/>
-+     * This implementation calls <code>retainAll()</code> on each collection.
-+     *
-+     * @param coll the collection to remove
-+     * @return true if the collection was modified
-+     * @throws UnsupportedOperationException if retainAll is unsupported
-+     */
-+    public boolean retainAll(final Collection<?> coll) {
-+        boolean changed = false;
-+        for (int i = this.all.length - 1; i >= 0; i--) {
-+            changed = (this.all[i].retainAll(coll) || changed);
-+        }
-+        return changed;
-+    }
-+
-+    /**
-+     * Removes all of the elements from this collection .
-+     * <p/>
-+     * This implementation calls <code>clear()</code> on each collection.
-+     *
-+     * @throws UnsupportedOperationException if clear is unsupported
-+     */
-+    public void clear() {
-+        for (int i = 0; i < this.all.length; ++i) {
-+            this.all[i].clear();
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Specify a CollectionMutator strategy instance to handle changes.
-+     *
-+     * @param mutator the mutator to use
-+     */
-+    public void setMutator(CollectionMutator<E> mutator) {
-+        this.mutator = mutator;
-+    }
-+
-+    /**
-+     * Add these Collections to the list of collections15 in this composite
-+     *
-+     * @param comps Collections to be appended to the composite
-+     */
-+    public void addComposited(Collection<? extends E>... comps) {
-+        ArrayList list = new ArrayList(Arrays.asList(this.all));
-+        list.addAll(Arrays.asList(comps));
-+        all = (Collection<E>[]) list.toArray(new Collection[list.size()]);
-+    }
-+
-+    /**
-+     * Add an additional collection to this composite.
-+     *
-+     * @param c the collection to add
-+     */
-+    public void addComposited(Collection<? extends E> c) {
-+        this.addComposited(new Collection[]{c});
-+    }
-+
-+    /**
-+     * Add two additional collections15 to this composite.
-+     *
-+     * @deprecated Superceded by the variable argument implementation of addComposited()
-+     * @param c the first collection to add
-+     * @param d the second collection to add
-+     */
-+    public void addComposited(Collection<? extends E> c, Collection<? extends E> d) {
-+        this.addComposited(new Collection[]{c, d});
-+    }
-+
-+    /**
-+     * Removes a collection from the those being decorated in this composite.
-+     *
-+     * @param coll collection to be removed
-+     */
-+    public void removeComposited(Collection<? extends E> coll) {
-+        ArrayList list = new ArrayList(this.all.length);
-+        list.addAll(Arrays.asList(this.all));
-+        list.remove(coll);
-+        this.all = (Collection<E>[]) list.toArray(new Collection[list.size()]);
-+    }
-+
-+    /**
-+     * Returns a new collection containing all of the elements
-+     *
-+     * @return A new ArrayList containing all of the elements in this composite.
-+     *         The new collection is <i>not</i> backed by this composite.
-+     */
-+    public Collection<E> toCollection() {
-+        return new ArrayList<E>(this);
-+    }
-+
-+    /**
-+     * Gets the collections15 being decorated.
-+     *
-+     * @return Unmodifiable collection of all collections15 in this composite.
-+     */
-+    public Collection<Collection<E>> getCollections() {
-+        return UnmodifiableList.decorate(Arrays.asList(this.all));
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Pluggable strategy to handle changes to the composite.
-+     */
-+    public interface CollectionMutator <E> {
-+
-+        /**
-+         * Called when an object is to be added to the composite.
-+         *
-+         * @param composite   the CompositeCollection being changed
-+         * @param collections all of the Collection instances in this CompositeCollection
-+         * @param obj         the object being added
-+         * @return true if the collection is changed
-+         * @throws UnsupportedOperationException if add is unsupported
-+         * @throws ClassCastException            if the object cannot be added due to its type
-+         * @throws NullPointerException          if the object cannot be added because its null
-+         * @throws IllegalArgumentException      if the object cannot be added
-+         */
-+        public boolean add(CompositeCollection<? extends E> composite, Collection<? extends E>[] collections, Object obj);
-+
-+        /**
-+         * Called when a collection is to be added to the composite.
-+         *
-+         * @param composite   the CompositeCollection being changed
-+         * @param collections all of the Collection instances in this CompositeCollection
-+         * @param coll        the collection being added
-+         * @return true if the collection is changed
-+         * @throws UnsupportedOperationException if add is unsupported
-+         * @throws ClassCastException            if the object cannot be added due to its type
-+         * @throws NullPointerException          if the object cannot be added because its null
-+         * @throws IllegalArgumentException      if the object cannot be added
-+         */
-+        public boolean addAll(CompositeCollection<? extends E> composite, Collection<? extends E>[] collections, Collection<? extends E> coll);
-+
-+        /**
-+         * Called when an object is to be removed to the composite.
-+         *
-+         * @param composite   the CompositeCollection being changed
-+         * @param collections all of the Collection instances in this CompositeCollection
-+         * @param obj         the object being removed
-+         * @return true if the collection is changed
-+         * @throws UnsupportedOperationException if removed is unsupported
-+         * @throws ClassCastException            if the object cannot be removed due to its type
-+         * @throws NullPointerException          if the object cannot be removed because its null
-+         * @throws IllegalArgumentException      if the object cannot be removed
-+         */
-+        public boolean remove(CompositeCollection<? extends E> composite, Collection<? extends E>[] collections, Object obj);
-+
-+    }
-+
-+}
-+
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/PredicatedCollection.java
-@@ -0,0 +1,138 @@
-+// GenericsNotes: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates another <code>Collection</code> to validate that additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This collection exists to provide validation for the decorated collection.
-+ * It is normally created to decorate an empty collection.
-+ * If an object cannot be added to the collection, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null entries are added to the collection.
-+ * <pre>Collection coll = PredicatedCollection.decorate(new ArrayList(), NotNullPredicate.INSTANCE);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedCollection <E> extends AbstractSerializableCollectionDecorator<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -5259182142076705162L;
-+
-+    /**
-+     * The predicate to use
-+     */
-+    protected final Predicate<? super E> predicate;
-+
-+    /**
-+     * Factory method to create a predicated (validating) collection.
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are validated.
-+     *
-+     * @param coll      the collection to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @return a new predicated collection
-+     * @throws IllegalArgumentException if collection or predicate is null
-+     * @throws IllegalArgumentException if the collection contains invalid elements
-+     */
-+    public static <E> Collection<E> decorate(Collection<E> coll, Predicate<? super E> predicate) {
-+        return new PredicatedCollection(coll, predicate);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are validated.
-+     *
-+     * @param coll      the collection to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if collection or predicate is null
-+     * @throws IllegalArgumentException if the collection contains invalid elements
-+     */
-+    protected PredicatedCollection(Collection<E> coll, Predicate<? super E> predicate) {
-+        super(coll);
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        this.predicate = predicate;
-+        for (Iterator<E> it = coll.iterator(); it.hasNext();) {
-+            validate(it.next());
-+        }
-+    }
-+
-+    /**
-+     * Validates the object being added to ensure it matches the predicate.
-+     * <p/>
-+     * The predicate itself should not throw an exception, but return false to
-+     * indicate that the object cannot be added.
-+     *
-+     * @param object the object being added
-+     * @throws IllegalArgumentException if the add is invalid
-+     */
-+    protected void validate(E object) {
-+        if (predicate.evaluate(object) == false) {
-+            throw new IllegalArgumentException("Cannot add Object '" + object + "' - Predicate rejected it");
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Override to validate the object being added to ensure it matches
-+     * the predicate.
-+     *
-+     * @param object the object being added
-+     * @return the result of adding to the underlying collection
-+     * @throws IllegalArgumentException if the add is invalid
-+     */
-+    public boolean add(E object) {
-+        validate(object);
-+        return getCollection().add(object);
-+    }
-+
-+    /**
-+     * Override to validate the objects being added to ensure they match
-+     * the predicate. If any one fails, no update is made to the underlying
-+     * collection.
-+     *
-+     * @param coll the collection being added
-+     * @return the result of adding to the underlying collection
-+     * @throws IllegalArgumentException if the add is invalid
-+     */
-+    public boolean addAll(Collection<? extends E> coll) {
-+        for (Iterator<? extends E> it = coll.iterator(); it.hasNext();) {
-+            validate(it.next());
-+        }
-+        return getCollection().addAll(coll);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/SynchronizedCollection.java
-@@ -0,0 +1,206 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates another <code>Collection</code> to synchronize its behaviour
-+ * for a multi-threaded environment.
-+ * <p/>
-+ * Iterators must be manually synchronized:
-+ * <pre>
-+ * synchronized (coll) {
-+ *   Iterator it = coll.iterator();
-+ *   // do stuff with iterator
-+ * }
-+ * </pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SynchronizedCollection <E> implements Collection<E>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 2412805092710877986L;
-+
-+    /**
-+     * The collection to decorate
-+     */
-+    protected final Collection<E> collection;
-+    /**
-+     * The object to lock on, needed for List/SortedSet views
-+     */
-+    protected final Object lock;
-+
-+    /**
-+     * Factory method to create a synchronized collection.
-+     *
-+     * @param coll the collection to decorate, must not be null
-+     * @return a new synchronized collection
-+     * @throws IllegalArgumentException if collection is null
-+     */
-+    public static <E> Collection<E> decorate(Collection<E> coll) {
-+        return new SynchronizedCollection<E>(coll);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param collection the collection to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    protected SynchronizedCollection(Collection<E> collection) {
-+        if (collection == null) {
-+            throw new IllegalArgumentException("Collection must not be null");
-+        }
-+        this.collection = collection;
-+        this.lock = this;
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param collection the collection to decorate, must not be null
-+     * @param lock       the lock object to use, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    protected SynchronizedCollection(Collection<E> collection, Object lock) {
-+        if (collection == null) {
-+            throw new IllegalArgumentException("Collection must not be null");
-+        }
-+        this.collection = collection;
-+        this.lock = lock;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E object) {
-+        synchronized (lock) {
-+            return collection.add(object);
-+        }
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        synchronized (lock) {
-+            return collection.addAll(coll);
-+        }
-+    }
-+
-+    public void clear() {
-+        synchronized (lock) {
-+            collection.clear();
-+        }
-+    }
-+
-+    public boolean contains(Object object) {
-+        synchronized (lock) {
-+            return collection.contains(object);
-+        }
-+    }
-+
-+    public boolean containsAll(Collection<?> coll) {
-+        synchronized (lock) {
-+            return collection.containsAll(coll);
-+        }
-+    }
-+
-+    public boolean isEmpty() {
-+        synchronized (lock) {
-+            return collection.isEmpty();
-+        }
-+    }
-+
-+    /**
-+     * Iterators must be manually synchronized.
-+     * <pre>
-+     * synchronized (coll) {
-+     *   Iterator it = coll.iterator();
-+     *   // do stuff with iterator
-+     * }
-+     *
-+     * @return an iterator that must be manually synchronized on the collection
-+     */
-+    public Iterator<E> iterator() {
-+        return collection.iterator();
-+    }
-+
-+    public Object[] toArray() {
-+        synchronized (lock) {
-+            return collection.toArray();
-+        }
-+    }
-+
-+    public <T> T[] toArray(T[] object) {
-+        synchronized (lock) {
-+            return collection.toArray(object);
-+        }
-+    }
-+
-+    public boolean remove(Object object) {
-+        synchronized (lock) {
-+            return collection.remove(object);
-+        }
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        synchronized (lock) {
-+            return collection.removeAll(coll);
-+        }
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        synchronized (lock) {
-+            return collection.retainAll(coll);
-+        }
-+    }
-+
-+    public int size() {
-+        synchronized (lock) {
-+            return collection.size();
-+        }
-+    }
-+
-+    public boolean equals(Object object) {
-+        synchronized (lock) {
-+            if (object == this) {
-+                return true;
-+            }
-+            return collection.equals(object);
-+        }
-+    }
-+
-+    public int hashCode() {
-+        synchronized (lock) {
-+            return collection.hashCode();
-+        }
-+    }
-+
-+    public String toString() {
-+        synchronized (lock) {
-+            return collection.toString();
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/TransformedCollection.java
-@@ -0,0 +1,141 @@
-+// GenericsNote: Converted, but unfortunately very little type-safety could be achieved without breaking Collection interface.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.ArrayList;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.List;
-+
-+/**
-+ * Decorates another <code>Collection</code> to transform objects that are added.
-+ * <p/>
-+ * The add methods are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Collection contract.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedCollection <I,O> extends AbstractSerializableCollectionDecorator {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 8692300188161871514L;
-+
-+    /**
-+     * The transformer to use
-+     */
-+    protected final Transformer<? super I, ? extends O> transformer;
-+
-+    /**
-+     * Factory method to create a transforming collection.
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param coll        the collection to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @return a new transformed collection
-+     * @throws IllegalArgumentException if collection or transformer is null
-+     */
-+    public static <I,O> Collection<O> decorate(Collection<I> coll, Transformer<? super I, ? extends O> transformer) {
-+        return new TransformedCollection<I, O>(coll, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param coll        the collection to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if collection or transformer is null
-+     */
-+    protected TransformedCollection(Collection<I> coll, Transformer<? super I, ? extends O> transformer) {
-+        super(coll);
-+        if (transformer == null) {
-+            throw new IllegalArgumentException("Transformer must not be null");
-+        }
-+        this.transformer = transformer;
-+    }
-+
-+    /**
-+     * Transforms an object.
-+     * <p/>
-+     * The transformer itself may throw an exception if necessary.
-+     *
-+     * @param object the object to transform
-+     * @return a transformed object
-+     */
-+    protected O transform(I object) {
-+        return transformer.transform(object);
-+    }
-+
-+    /**
-+     * Transforms a collection.
-+     * <p/>
-+     * The transformer itself may throw an exception if necessary.
-+     *
-+     * @param coll the collection to transform
-+     * @return a transformed object
-+     */
-+    protected Collection<O> transform(Collection<? extends I> coll) {
-+        List<O> list = new ArrayList<O>(coll.size());
-+        for (Iterator<? extends I> it = coll.iterator(); it.hasNext();) {
-+            list.add(transform(it.next()));
-+        }
-+        return list;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(Object object) {
-+        O transformed = transform((I) object);
-+        return getCollection().add(transformed);
-+    }
-+
-+    /**
-+     * A better typed version of the add method (although breaks the Collection interface).
-+     */
-+    public boolean addTyped(I object) {
-+        return add(object);
-+    }
-+
-+    public boolean addAll(Collection coll) {
-+        Collection<O> col2 = transform((Collection<? extends I>) coll);
-+        return getCollection().addAll(col2);
-+    }
-+
-+    /**
-+     * A better typed version of the addAll method (although breaks the Collection interface).
-+     */
-+    public boolean addAllTyped(Collection<? extends I> coll) {
-+        return addAll(coll);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/TypedCollection.java
-@@ -0,0 +1,61 @@
-+// GenericsNote: Not converted, deprecated.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+import java.util.Collection;
-+
-+/**
-+ * Decorates a <code>Collection</code> to validate that elements added are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ * @deprecated Type safe classes are no longer required under 1.5.
-+ */
-+public class TypedCollection {
-+
-+    /**
-+     * Factory method to create a typed collection.
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are validated.
-+     *
-+     * @param coll the collection to decorate, must not be null
-+     * @param type the type to allow into the collection, must not be null
-+     * @return a new typed collection
-+     * @throws IllegalArgumentException if collection or type is null
-+     * @throws IllegalArgumentException if the collection contains invalid elements
-+     */
-+    public static Collection decorate(Collection coll, Class type) {
-+        return new PredicatedCollection(coll, InstanceofPredicate.getInstance(type));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedCollection() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/UnmodifiableBoundedCollection.java
-@@ -0,0 +1,141 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import org.apache.commons.collections15.BoundedCollection;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * <code>UnmodifiableBoundedCollection</code> decorates another
-+ * <code>BoundedCollection</code> to ensure it can't be altered.
-+ * <p/>
-+ * If a BoundedCollection is first wrapped in some other collection decorator,
-+ * such as synchronized or predicated, the BoundedCollection methods are no
-+ * longer accessible.
-+ * The factory on this class will attempt to retrieve the bounded nature by
-+ * examining the package scope variables.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableBoundedCollection <E> extends AbstractSerializableCollectionDecorator<E> implements BoundedCollection<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -7112672385450340330L;
-+
-+    /**
-+     * Factory method to create an unmodifiable bounded collection.
-+     *
-+     * @param coll the <code>BoundedCollection</code> to decorate, must not be null
-+     * @return a new unmodifiable bounded collection
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    public static <E> BoundedCollection<E> decorate(BoundedCollection<E> coll) {
-+        return new UnmodifiableBoundedCollection<E>(coll);
-+    }
-+
-+    /**
-+     * Factory method to create an unmodifiable bounded collection.
-+     * <p/>
-+     * This method is capable of drilling down through up to 1000 other decorators
-+     * to find a suitable BoundedCollection.
-+     *
-+     * @param coll the <code>BoundedCollection</code> to decorate, must not be null
-+     * @return a new unmodifiable bounded collection
-+     * @throws IllegalArgumentException if bag is null
-+     */
-+    public static <E> BoundedCollection<E> decorateUsing(Collection<E> coll) {
-+        if (coll == null) {
-+            throw new IllegalArgumentException("The collection must not be null");
-+        }
-+        
-+        // handle decorators
-+        for (int i = 0; i < 1000; i++) {  // counter to prevent infinite looping
-+            if (coll instanceof BoundedCollection) {
-+                break;  // normal loop exit
-+            } else if (coll instanceof AbstractCollectionDecorator) {
-+                coll = ((AbstractCollectionDecorator<E>) coll).collection;
-+            } else if (coll instanceof SynchronizedCollection) {
-+                coll = ((SynchronizedCollection<E>) coll).collection;
-+            } else {
-+                break;  // normal loop exit
-+            }
-+        }
-+
-+        if (coll instanceof BoundedCollection == false) {
-+            throw new IllegalArgumentException("The collection is not a bounded collection");
-+        }
-+        return new UnmodifiableBoundedCollection<E>((BoundedCollection) coll);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param coll the collection to decorate, must not be null
-+     * @throws IllegalArgumentException if coll is null
-+     */
-+    private UnmodifiableBoundedCollection(BoundedCollection<E> coll) {
-+        super(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    public boolean isFull() {
-+        return ((BoundedCollection) collection).isFull();
-+    }
-+
-+    public int maxSize() {
-+        return ((BoundedCollection) collection).maxSize();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/UnmodifiableCollection.java
-@@ -0,0 +1,97 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.collection;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates another <code>Collection</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableCollection <E> extends AbstractSerializableCollectionDecorator<E> implements Unmodifiable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -239892006883819945L;
-+
-+    /**
-+     * Factory method to create an unmodifiable collection.
-+     * <p/>
-+     * If the collection passed in is already unmodifiable, it is returned.
-+     *
-+     * @param coll the collection to decorate, must not be null
-+     * @return an unmodifiable collection
-+     * @throws IllegalArgumentException if collection is null
-+     */
-+    public static <E> Collection<E> decorate(Collection<E> coll) {
-+        if (coll instanceof Unmodifiable) {
-+            return coll;
-+        }
-+        return new UnmodifiableCollection<E>(coll);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param coll the collection to decorate, must not be null
-+     * @throws IllegalArgumentException if collection is null
-+     */
-+    private UnmodifiableCollection(Collection<E> coll) {
-+        super(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/collection/package.html
-@@ -0,0 +1,35 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:20 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link java.util.Collection Collection} interface.
-+<p>
-+The following implementations are provided in the package:
-+<ul>
-+<li>CompositeCollection - a collection that combines multiple collections into one
-+</ul>
-+The following decorators are provided in the package:
-+<ul>
-+<li>Synchronized - synchronizes method access for multi-threaded environments
-+<li>Unmodifiable - ensures the collection cannot be altered
-+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
-+<li>Typed - ensures that only elements that are of a specific type can be added
-+<li>Transformed - transforms elements as they are added
-+</ul>
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/BooleanComparator.java
-@@ -0,0 +1,194 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.comparators;
-+
-+import java.io.Serializable;
-+import java.util.Comparator;
-+
-+/**
-+ * A {@link Comparator} for {@link Boolean} objects that can sort either
-+ * true or false first.
-+ * <p/>
-+ *
-+ * @author Matt Hall, John Watkinson, Rodney Waldhoff
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @see #getTrueFirstComparator()
-+ * @see #getFalseFirstComparator()
-+ * @see #getBooleanComparator(boolean)
-+ * @since Commons Collections 3.0
-+ */
-+public final class BooleanComparator implements Comparator<Boolean>, Serializable {
-+
-+    /**
-+     * Serialization version.
-+     */
-+    private static final long serialVersionUID = 1830042991606340609L;
-+
-+    /**
-+     * Constant "true first" reference.
-+     */
-+    private static final BooleanComparator TRUE_FIRST = new BooleanComparator(true);
-+
-+    /**
-+     * Constant "false first" reference.
-+     */
-+    private static final BooleanComparator FALSE_FIRST = new BooleanComparator(false);
-+
-+    /**
-+     * <code>true</code> iff <code>true</code> values sort before <code>false</code> values.
-+     */
-+    private boolean trueFirst = false;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a BooleanComparator instance that sorts
-+     * <code>true</code> values before <code>false</code> values.
-+     * <p />
-+     * Clients are encouraged to use the value returned from
-+     * this method instead of constructing a new instance
-+     * to reduce allocation and garbage collection overhead when
-+     * multiple BooleanComparators may be used in the same
-+     * virtual machine.
-+     *
-+     * @return the true first singleton BooleanComparator
-+     */
-+    public static BooleanComparator getTrueFirstComparator() {
-+        return TRUE_FIRST;
-+    }
-+
-+    /**
-+     * Returns a BooleanComparator instance that sorts
-+     * <code>false</code> values before <code>true</code> values.
-+     * <p />
-+     * Clients are encouraged to use the value returned from
-+     * this method instead of constructing a new instance
-+     * to reduce allocation and garbage collection overhead when
-+     * multiple BooleanComparators may be used in the same
-+     * virtual machine.
-+     *
-+     * @return the false first singleton BooleanComparator
-+     */
-+    public static BooleanComparator getFalseFirstComparator() {
-+        return FALSE_FIRST;
-+    }
-+
-+    /**
-+     * Returns a BooleanComparator instance that sorts
-+     * <code><i>trueFirst</i></code> values before
-+     * <code>&#x21;<i>trueFirst</i></code> values.
-+     * <p />
-+     * Clients are encouraged to use the value returned from
-+     * this method instead of constructing a new instance
-+     * to reduce allocation and garbage collection overhead when
-+     * multiple BooleanComparators may be used in the same
-+     * virtual machine.
-+     *
-+     * @param trueFirst when <code>true</code>, sort
-+     *                  <code>true</code> <code>Boolean</code>s before <code>false</code>
-+     * @return a singleton BooleanComparator instance
-+     */
-+    public static BooleanComparator getBooleanComparator(boolean trueFirst) {
-+        return trueFirst ? TRUE_FIRST : FALSE_FIRST;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Creates a <code>BooleanComparator</code> that sorts
-+     * <code>false</code> values before <code>true</code> values.
-+     * <p/>
-+     * Equivalent to {@link #BooleanComparator(boolean) BooleanComparator(false)}.
-+     * <p/>
-+     * Please use the static factory instead whenever possible.
-+     */
-+    public BooleanComparator() {
-+        this(false);
-+    }
-+
-+    /**
-+     * Creates a <code>BooleanComparator</code> that sorts
-+     * <code><i>trueFirst</i></code> values before
-+     * <code>&#x21;<i>trueFirst</i></code> values.
-+     * <p/>
-+     * Please use the static factories instead whenever possible.
-+     *
-+     * @param trueFirst when <code>true</code>, sort
-+     *                  <code>true</code> boolean values before <code>false</code>
-+     */
-+    public BooleanComparator(boolean trueFirst) {
-+        this.trueFirst = trueFirst;
-+    }
-+
-+    /**
-+     * Compares two non-<code>null</code> <code>Boolean</code> objects
-+     * according to the value of {@link #trueFirst}.
-+     *
-+     * @param b1 the first boolean to compare
-+     * @param b2 the second boolean to compare
-+     * @return negative if obj1 is less, positive if greater, zero if equal
-+     * @throws NullPointerException when either argument <code>null</code>
-+     */
-+    public int compare(Boolean b1, Boolean b2) {
-+        boolean v1 = b1.booleanValue();
-+        boolean v2 = b2.booleanValue();
-+
-+        return (v1 ^ v2) ? ((v1 ^ trueFirst) ? 1 : -1) : 0;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implement a hash code for this comparator that is consistent with
-+     * {@link #equals(Object) equals}.
-+     *
-+     * @return a hash code for this comparator.
-+     */
-+    public int hashCode() {
-+        int hash = "BooleanComparator".hashCode();
-+        return trueFirst ? -1 * hash : hash;
-+    }
-+
-+    /**
-+     * Returns <code>true</code> iff <i>that</i> Object is
-+     * is a {@link Comparator} whose ordering is known to be
-+     * equivalent to mine.
-+     * <p/>
-+     * This implementation returns <code>true</code>
-+     * iff <code><i>that</i></code> is a {@link BooleanComparator}
-+     * whose {@link #trueFirst} value is equal to mine.
-+     *
-+     * @param object the object to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object object) {
-+        return (this == object) || ((object instanceof BooleanComparator) && (this.trueFirst == ((BooleanComparator) object).trueFirst));
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns <code>true</code> iff
-+     * I sort <code>true</code> values before
-+     * <code>false</code> values.  In other words,
-+     * returns <code>true</code> iff
-+     * {@link #compare(Boolean,Boolean) compare(Boolean.FALSE,Boolean.TRUE)}
-+     * returns a positive value.
-+     *
-+     * @return the trueFirst flag
-+     */
-+    public boolean sortsTrueFirst() {
-+        return trueFirst;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/ComparableComparator.java
-@@ -0,0 +1,128 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.comparators;
-+
-+import java.io.Serializable;
-+import java.util.Comparator;
-+
-+/**
-+ * A {@link Comparator Comparator} that compares
-+ * {@link Comparable Comparable} objects.
-+ * <p />
-+ * This Comparator is useful, for example,
-+ * for enforcing the natural order in custom implementations
-+ * of SortedSet and SortedMap.
-+ * <p />
-+ * Note: In the 2.0 and 2.1 releases of Commons Collections,
-+ * this class would throw a {@link ClassCastException} if
-+ * either of the arguments to {@link #compare(Object, Object) compare}
-+ * were <code>null</code>, not {@link Comparable Comparable},
-+ * or for which {@link Comparable#compareTo(Object) compareTo} gave
-+ * inconsistent results.  This is no longer the case.  See
-+ * {@link #compare(Object, Object) compare} for details.
-+ *
-+ * @author Matt Hall, John Watkinson, Henri Yandell
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @see java.util.Collections#reverseOrder()
-+ * @since Commons Collections 2.0
-+ */
-+public class ComparableComparator<T extends Comparable> implements Comparator<T>, Serializable {
-+
-+    /**
-+     * Serialization version.
-+     */
-+    private static final long serialVersionUID = -291439688585137865L;
-+
-+    /**
-+     * The singleton instance.
-+     */
-+    private static final ComparableComparator instance = new ComparableComparator();
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the singleton instance of a ComparableComparator.
-+     * <p/>
-+     * Developers are encouraged to use the comparator returned from this method
-+     * instead of constructing a new instance to reduce allocation and GC overhead
-+     * when multiple comparable comparators may be used in the same VM.
-+     *
-+     * @return the singleton ComparableComparator
-+     */
-+	public static <T> Comparator<T> getInstance() {
-+        return instance;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor whose use should be avoided.
-+     * <p/>
-+     * Please use the {@link #getInstance()} method whenever possible.
-+     */
-+    public ComparableComparator() {
-+        super();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compare the two {@link Comparable Comparable} arguments.
-+     * This method is equivalent to:
-+     * <pre>((Comparable)obj1).compareTo(obj2)</pre>
-+     *
-+     * @param obj1 the first object to compare
-+     * @param obj2 the second object to compare
-+     * @return negative if obj1 is less, positive if greater, zero if equal
-+     * @throws NullPointerException when <i>obj1</i> is <code>null</code>,
-+     *                              or when <code>((Comparable)obj1).compareTo(obj2)</code> does
-+     * @throws ClassCastException   when <i>obj1</i> is not a <code>Comparable</code>,
-+     *                              or when <code>((Comparable)obj1).compareTo(obj2)</code> does
-+     */
-+    public int compare(T obj1, T obj2) {
-+        return obj1.compareTo(obj2);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implement a hash code for this comparator that is consistent with
-+     * {@link #equals(Object) equals}.
-+     *
-+     * @return a hash code for this comparator.
-+     * @since Commons Collections 3.0
-+     */
-+    public int hashCode() {
-+        return "ComparableComparator".hashCode();
-+    }
-+
-+    /**
-+     * Returns <code>true</code> iff <i>that</i> Object is
-+     * is a {@link Comparator Comparator} whose ordering is
-+     * known to be equivalent to mine.
-+     * <p/>
-+     * This implementation returns <code>true</code>
-+     * iff <code><i>object</i>.{@link Object#getClass() getClass()}</code>
-+     * equals <code>this.getClass()</code>.
-+     * Subclasses may want to override this behavior to remain consistent
-+     * with the {@link Comparator#equals(Object)} contract.
-+     *
-+     * @param object the object to compare with
-+     * @return true if equal
-+     * @since Commons Collections 3.0
-+     */
-+    public boolean equals(Object object) {
-+        return (this == object) || ((null != object) && (object.getClass().equals(this.getClass())));
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/ComparatorChain.java
-@@ -0,0 +1,347 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.comparators;
-+
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * <p>A ComparatorChain is a Comparator that wraps one or
-+ * more Comparators in sequence.  The ComparatorChain
-+ * calls each Comparator in sequence until either 1)
-+ * any single Comparator returns a non-zero result
-+ * (and that result is then returned),
-+ * or 2) the ComparatorChain is exhausted (and zero is
-+ * returned).  This type of sorting is very similar
-+ * to multi-column sorting in SQL, and this class
-+ * allows Java classes to emulate that kind of behaviour
-+ * when sorting a List.</p>
-+ * <p/>
-+ * <p>To further facilitate SQL-like sorting, the order of
-+ * any single Comparator in the list can be reversed.</p>
-+ * <p/>
-+ * <p>Calling a method that adds new Comparators or
-+ * changes the ascend/descend sort <i>after compare(Object,
-+ * Object) has been called</i> will result in an
-+ * UnsupportedOperationException.  However, <i>take care</i>
-+ * to not alter the underlying List of Comparators
-+ * or the BitSet that defines the sort order.</p>
-+ * <p/>
-+ * <p>Instances of ComparatorChain are not synchronized.
-+ * The class is not thread-safe at construction time, but
-+ * it <i>is</i> thread-safe to perform multiple comparisons
-+ * after all the setup operations are complete.</p>
-+ *
-+ * @author Matt Hall, John Watkinson, Morgan Delagrange
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 2.0
-+ */
-+public class ComparatorChain <T> implements Comparator<T>, Serializable {
-+
-+    /**
-+     * Serialization version from Collections 2.0.
-+     */
-+    private static final long serialVersionUID = -721644942746081630L;
-+
-+    /**
-+     * The list of comparators in the chain.
-+     */
-+    protected List<Comparator<T>> comparatorChain = null;
-+    /**
-+     * Order - false (clear) = ascend; true (set) = descend.
-+     */
-+    protected BitSet orderingBits = null;
-+    /**
-+     * Whether the chain has been "locked".
-+     */
-+    protected boolean isLocked = false;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Construct a ComparatorChain with no Comparators.
-+     * You must add at least one Comparator before calling
-+     * the compare(Object,Object) method, or an
-+     * UnsupportedOperationException is thrown
-+     */
-+    public ComparatorChain() {
-+        this(new ArrayList<Comparator<T>>(), new BitSet());
-+    }
-+
-+    /**
-+     * Construct a ComparatorChain with a single Comparator,
-+     * sorting in the forward order
-+     *
-+     * @param comparator First comparator in the Comparator chain
-+     */
-+    public ComparatorChain(Comparator<T> comparator) {
-+        this(comparator, false);
-+    }
-+
-+    /**
-+     * Construct a Comparator chain with a single Comparator,
-+     * sorting in the given order
-+     *
-+     * @param comparator First Comparator in the ComparatorChain
-+     * @param reverse    false = forward sort; true = reverse sort
-+     */
-+    public ComparatorChain(Comparator<T> comparator, boolean reverse) {
-+        comparatorChain = new ArrayList<Comparator<T>>();
-+        comparatorChain.add(comparator);
-+        orderingBits = new BitSet(1);
-+        if (reverse == true) {
-+            orderingBits.set(0);
-+        }
-+    }
-+
-+    /**
-+     * Construct a ComparatorChain from the Comparators in the
-+     * List.  All Comparators will default to the forward
-+     * sort order.
-+     *
-+     * @param list List of Comparators
-+     * @see #ComparatorChain(List,BitSet)
-+     */
-+    public ComparatorChain(List<Comparator<T>> list) {
-+        this(list, new BitSet(list.size()));
-+    }
-+
-+    /**
-+     * Construct a ComparatorChain from the Comparators in the
-+     * given List.  The sort order of each column will be
-+     * drawn from the given BitSet.  When determining the sort
-+     * order for Comparator at index <i>i</i> in the List,
-+     * the ComparatorChain will call BitSet.get(<i>i</i>).
-+     * If that method returns <i>false</i>, the forward
-+     * sort order is used; a return value of <i>true</i>
-+     * indicates reverse sort order.
-+     *
-+     * @param list List of Comparators.  NOTE: This constructor does not perform a
-+     *             defensive copy of the list
-+     * @param bits Sort order for each Comparator.  Extra bits are ignored,
-+     *             unless extra Comparators are added by another method.
-+     */
-+    public ComparatorChain(List<Comparator<T>> list, BitSet bits) {
-+        comparatorChain = list;
-+        orderingBits = bits;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Add a Comparator to the end of the chain using the
-+     * forward sort order
-+     *
-+     * @param comparator Comparator with the forward sort order
-+     */
-+    public void addComparator(Comparator<T> comparator) {
-+        addComparator(comparator, false);
-+    }
-+
-+    /**
-+     * Add a Comparator to the end of the chain using the
-+     * given sort order
-+     *
-+     * @param comparator Comparator to add to the end of the chain
-+     * @param reverse    false = forward sort order; true = reverse sort order
-+     */
-+    public void addComparator(Comparator<T> comparator, boolean reverse) {
-+        checkLocked();
-+
-+        comparatorChain.add(comparator);
-+        if (reverse == true) {
-+            orderingBits.set(comparatorChain.size() - 1);
-+        }
-+    }
-+
-+    /**
-+     * Replace the Comparator at the given index, maintaining
-+     * the existing sort order.
-+     *
-+     * @param index      index of the Comparator to replace
-+     * @param comparator Comparator to place at the given index
-+     * @throws IndexOutOfBoundsException if index < 0 or index >= size()
-+     */
-+    public void setComparator(int index, Comparator<T> comparator) throws IndexOutOfBoundsException {
-+        setComparator(index, comparator, false);
-+    }
-+
-+    /**
-+     * Replace the Comparator at the given index in the
-+     * ComparatorChain, using the given sort order
-+     *
-+     * @param index      index of the Comparator to replace
-+     * @param comparator Comparator to set
-+     * @param reverse    false = forward sort order; true = reverse sort order
-+     */
-+    public void setComparator(int index, Comparator<T> comparator, boolean reverse) {
-+        checkLocked();
-+
-+        comparatorChain.set(index, comparator);
-+        if (reverse == true) {
-+            orderingBits.set(index);
-+        } else {
-+            orderingBits.clear(index);
-+        }
-+    }
-+
-+
-+    /**
-+     * Change the sort order at the given index in the
-+     * ComparatorChain to a forward sort.
-+     *
-+     * @param index Index of the ComparatorChain
-+     */
-+    public void setForwardSort(int index) {
-+        checkLocked();
-+        orderingBits.clear(index);
-+    }
-+
-+    /**
-+     * Change the sort order at the given index in the
-+     * ComparatorChain to a reverse sort.
-+     *
-+     * @param index Index of the ComparatorChain
-+     */
-+    public void setReverseSort(int index) {
-+        checkLocked();
-+        orderingBits.set(index);
-+    }
-+
-+    /**
-+     * Number of Comparators in the current ComparatorChain.
-+     *
-+     * @return Comparator count
-+     */
-+    public int size() {
-+        return comparatorChain.size();
-+    }
-+
-+    /**
-+     * Determine if modifications can still be made to the
-+     * ComparatorChain.  ComparatorChains cannot be modified
-+     * once they have performed a comparison.
-+     *
-+     * @return true = ComparatorChain cannot be modified; false =
-+     *         ComparatorChain can still be modified.
-+     */
-+    public boolean isLocked() {
-+        return isLocked;
-+    }
-+
-+    // throw an exception if the ComparatorChain is locked
-+    private void checkLocked() {
-+        if (isLocked == true) {
-+            throw new UnsupportedOperationException("Comparator ordering cannot be changed after the first comparison is performed");
-+        }
-+    }
-+
-+    private void checkChainIntegrity() {
-+        if (comparatorChain.size() == 0) {
-+            throw new UnsupportedOperationException("ComparatorChains must contain at least one Comparator");
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Perform comparisons on the Objects as per
-+     * Comparator.compare(o1,o2).
-+     *
-+     * @param o1 the first object to compare
-+     * @param o2 the second object to compare
-+     * @return -1, 0, or 1
-+     * @throws UnsupportedOperationException if the ComparatorChain does not contain at least one
-+     *                                       Comparator
-+     */
-+    public int compare(T o1, T o2) throws UnsupportedOperationException {
-+        if (isLocked == false) {
-+            checkChainIntegrity();
-+            isLocked = true;
-+        }
-+
-+        // iterate over all comparators in the chain
-+        Iterator<Comparator<T>> comparators = comparatorChain.iterator();
-+        for (int comparatorIndex = 0; comparators.hasNext(); ++comparatorIndex) {
-+
-+            Comparator<T> comparator = comparators.next();
-+            int retval = comparator.compare(o1, o2);
-+            if (retval != 0) {
-+                // invert the order if it is a reverse sort
-+                if (orderingBits.get(comparatorIndex) == true) {
-+                    if (Integer.MIN_VALUE == retval) {
-+                        retval = Integer.MAX_VALUE;
-+                    } else {
-+                        retval *= -1;
-+                    }
-+                }
-+
-+                return retval;
-+            }
-+
-+        }
-+
-+        // if comparators are exhausted, return 0
-+        return 0;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implement a hash code for this comparator that is consistent with
-+     * {@link #equals(Object) equals}.
-+     *
-+     * @return a suitable hash code
-+     * @since Commons Collections 3.0
-+     */
-+    public int hashCode() {
-+        int hash = 0;
-+        if (null != comparatorChain) {
-+            hash ^= comparatorChain.hashCode();
-+        }
-+        if (null != orderingBits) {
-+            hash ^= orderingBits.hashCode();
-+        }
-+        return hash;
-+    }
-+
-+    /**
-+     * Returns <code>true</code> iff <i>that</i> Object is
-+     * is a {@link Comparator} whose ordering is known to be
-+     * equivalent to mine.
-+     * <p/>
-+     * This implementation returns <code>true</code>
-+     * iff <code><i>object</i>.{@link Object#getClass() getClass()}</code>
-+     * equals <code>this.getClass()</code>, and the underlying
-+     * comparators and order bits are equal.
-+     * Subclasses may want to override this behavior to remain consistent
-+     * with the {@link Comparator#equals(Object)} contract.
-+     *
-+     * @param object the object to compare with
-+     * @return true if equal
-+     * @since Commons Collections 3.0
-+     */
-+    public boolean equals(Object object) {
-+        if (this == object) {
-+            return true;
-+        } else if (null == object) {
-+            return false;
-+        } else if (object.getClass().equals(this.getClass())) {
-+            ComparatorChain chain = (ComparatorChain) object;
-+            return ((null == orderingBits ? null == chain.orderingBits : orderingBits.equals(chain.orderingBits)) && (null == comparatorChain ? null == chain.comparatorChain : comparatorChain.equals(chain.comparatorChain)));
-+        } else {
-+            return false;
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/FixedOrderComparator.java
-@@ -0,0 +1,267 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.comparators;
-+
-+import java.util.*;
-+
-+/**
-+ * A Comparator which imposes a specific order on a specific set of Objects.
-+ * Objects are presented to the FixedOrderComparator in a specified order and
-+ * subsequent calls to {@link #compare(Object, Object) compare} yield that order.
-+ * For example:
-+ * <pre>
-+ * String[] planets = {"Mercury", "Venus", "Earth", "Mars"};
-+ * FixedOrderComparator distanceFromSun = new FixedOrderComparator(planets);
-+ * Arrays.sort(planets);                     // Sort to alphabetical order
-+ * Arrays.sort(planets, distanceFromSun);    // Back to original order
-+ * </pre>
-+ * <p/>
-+ * Once <code>compare</code> has been called, the FixedOrderComparator is locked
-+ * and attempts to modify it yield an UnsupportedOperationException.
-+ * <p/>
-+ * Instances of FixedOrderComparator are not synchronized.  The class is not
-+ * thread-safe at construction time, but it is thread-safe to perform
-+ * multiple comparisons  after all the setup operations are complete.
-+ *
-+ * @author David Leppik
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Janek Bogucki
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 3.0
-+ */
-+public class FixedOrderComparator <T> implements Comparator<T> {
-+
-+    /**
-+     * Behavior when comparing unknown Objects:
-+     * unknown objects compare as before known Objects.
-+     */
-+    public static final int UNKNOWN_BEFORE = 0;
-+
-+    /**
-+     * Behavior when comparing unknown Objects:
-+     * unknown objects compare as after known Objects.
-+     */
-+    public static final int UNKNOWN_AFTER = 1;
-+
-+    /**
-+     * Behavior when comparing unknown Objects:
-+     * unknown objects cause a IllegalArgumentException to be thrown.
-+     * This is the default behavior.
-+     */
-+    public static final int UNKNOWN_THROW_EXCEPTION = 2;
-+
-+    /**
-+     * Internal map of object to position
-+     */
-+    private final Map<T, Integer> map = new HashMap<T, Integer>();
-+    /**
-+     * Counter used in determining the position in the map
-+     */
-+    private int counter = 0;
-+    /**
-+     * Is the comparator locked against further change
-+     */
-+    private boolean isLocked = false;
-+    /**
-+     * The behaviour in the case of an unknown object
-+     */
-+    private int unknownObjectBehavior = UNKNOWN_THROW_EXCEPTION;
-+
-+    // Constructors
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs an empty FixedOrderComparator.
-+     */
-+    public FixedOrderComparator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a FixedOrderComparator which uses the order of the given array
-+     * to compare the objects.
-+     * <p/>
-+     * The array is copied, so later changes will not affect the comparator.
-+     *
-+     * @param items the items that the comparator can compare in order
-+     * @throws IllegalArgumentException if the array is null
-+     */
-+    public FixedOrderComparator(T[] items) {
-+        super();
-+        if (items == null) {
-+            throw new IllegalArgumentException("The list of items must not be null");
-+        }
-+        for (int i = 0; i < items.length; i++) {
-+            add(items[i]);
-+        }
-+    }
-+
-+    /**
-+     * Constructs a FixedOrderComparator which uses the order of the given list
-+     * to compare the objects.
-+     * <p/>
-+     * The list is copied, so later changes will not affect the comparator.
-+     *
-+     * @param items the items that the comparator can compare in order
-+     * @throws IllegalArgumentException if the list is null
-+     */
-+    public FixedOrderComparator(List<T> items) {
-+        super();
-+        if (items == null) {
-+            throw new IllegalArgumentException("The list of items must not be null");
-+        }
-+        for (Iterator<T> it = items.iterator(); it.hasNext();) {
-+            add(it.next());
-+        }
-+    }
-+
-+    // Bean methods / state querying methods
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns true if modifications cannot be made to the FixedOrderComparator.
-+     * FixedOrderComparators cannot be modified once they have performed a comparison.
-+     *
-+     * @return true if attempts to change the FixedOrderComparator yield an
-+     *         UnsupportedOperationException, false if it can be changed.
-+     */
-+    public boolean isLocked() {
-+        return isLocked;
-+    }
-+
-+    /**
-+     * Checks to see whether the comparator is now locked against further changes.
-+     *
-+     * @throws UnsupportedOperationException if the comparator is locked
-+     */
-+    protected void checkLocked() {
-+        if (isLocked()) {
-+            throw new UnsupportedOperationException("Cannot modify a FixedOrderComparator after a comparison");
-+        }
-+    }
-+
-+    /**
-+     * Gets the behavior for comparing unknown objects.
-+     *
-+     * @return the flag for unknown behaviour - UNKNOWN_AFTER,
-+     *         UNKNOWN_BEFORE or UNKNOWN_THROW_EXCEPTION
-+     */
-+    public int getUnknownObjectBehavior() {
-+        return unknownObjectBehavior;
-+    }
-+
-+    /**
-+     * Sets the behavior for comparing unknown objects.
-+     *
-+     * @param unknownObjectBehavior the flag for unknown behaviour -
-+     *                              UNKNOWN_AFTER, UNKNOWN_BEFORE or UNKNOWN_THROW_EXCEPTION
-+     * @throws UnsupportedOperationException if a comparison has been performed
-+     * @throws IllegalArgumentException      if the unknown flag is not valid
-+     */
-+    public void setUnknownObjectBehavior(int unknownObjectBehavior) {
-+        checkLocked();
-+        if (unknownObjectBehavior != UNKNOWN_AFTER && unknownObjectBehavior != UNKNOWN_BEFORE && unknownObjectBehavior != UNKNOWN_THROW_EXCEPTION) {
-+            throw new IllegalArgumentException("Unrecognised value for unknown behaviour flag");
-+        }
-+        this.unknownObjectBehavior = unknownObjectBehavior;
-+    }
-+
-+    // Methods for adding items
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Adds an item, which compares as after all items known to the Comparator.
-+     * If the item is already known to the Comparator, its old position is
-+     * replaced with the new position.
-+     *
-+     * @param obj the item to be added to the Comparator.
-+     * @return true if obj has been added for the first time, false if
-+     *         it was already known to the Comparator.
-+     * @throws UnsupportedOperationException if a comparison has already been made
-+     */
-+    public boolean add(T obj) {
-+        checkLocked();
-+        Integer position = map.put(obj, new Integer(counter++));
-+        return (position == null);
-+    }
-+
-+    /**
-+     * Adds a new item, which compares as equal to the given existing item.
-+     *
-+     * @param existingObj an item already in the Comparator's set of
-+     *                    known objects
-+     * @param newObj      an item to be added to the Comparator's set of
-+     *                    known objects
-+     * @return true if newObj has been added for the first time, false if
-+     *         it was already known to the Comparator.
-+     * @throws IllegalArgumentException      if existingObject is not in the
-+     *                                       Comparator's set of known objects.
-+     * @throws UnsupportedOperationException if a comparison has already been made
-+     */
-+    public boolean addAsEqual(T existingObj, T newObj) {
-+        checkLocked();
-+        Integer position = (Integer) map.get(existingObj);
-+        if (position == null) {
-+            throw new IllegalArgumentException(existingObj + " not known to " + this);
-+        }
-+        Integer result = map.put(newObj, position);
-+        return (result == null);
-+    }
-+
-+    // Comparator methods
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares two objects according to the order of this Comparator.
-+     * <p/>
-+     * It is important to note that this class will throw an IllegalArgumentException
-+     * in the case of an unrecognised object. This is not specified in the
-+     * Comparator interface, but is the most appropriate exception.
-+     *
-+     * @param obj1 the first object to compare
-+     * @param obj2 the second object to compare
-+     * @return negative if obj1 is less, positive if greater, zero if equal
-+     * @throws IllegalArgumentException if obj1 or obj2 are not known
-+     *                                  to this Comparator and an alternative behavior has not been set
-+     *                                  via {@link #setUnknownObjectBehavior(int)}.
-+     */
-+    public int compare(T obj1, T obj2) {
-+        isLocked = true;
-+        Integer position1 = (Integer) map.get(obj1);
-+        Integer position2 = (Integer) map.get(obj2);
-+        if (position1 == null || position2 == null) {
-+            switch (unknownObjectBehavior) {
-+                case UNKNOWN_BEFORE:
-+                    if (position1 == null) {
-+                        return (position2 == null) ? 0 : -1;
-+                    } else {
-+                        return 1;
-+                    }
-+                case UNKNOWN_AFTER:
-+                    if (position1 == null) {
-+                        return (position2 == null) ? 0 : 1;
-+                    } else {
-+                        return -1;
-+                    }
-+                case UNKNOWN_THROW_EXCEPTION:
-+                    Object unknownObj = (position1 == null) ? obj1 : obj2;
-+                    throw new IllegalArgumentException("Attempting to compare unknown object " + unknownObj);
-+                default :
-+                    throw new UnsupportedOperationException("Unknown unknownObjectBehavior: " + unknownObjectBehavior);
-+            }
-+        } else {
-+            return position1.compareTo(position2);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/NullComparator.java
-@@ -0,0 +1,157 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.comparators;
-+
-+import java.io.Serializable;
-+import java.util.Comparator;
-+
-+/**
-+ * A Comparator that will compare nulls to be either lower or higher than
-+ * other objects.
-+ *
-+ * @author Matt Hall, John Watkinson, Michael A. Smith
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @since Commons Collections 2.0
-+ */
-+public class NullComparator <T> implements Comparator<T>, Serializable {
-+
-+    /**
-+     * Serialization version.
-+     */
-+    private static final long serialVersionUID = -5820772575483504339L;
-+
-+    /**
-+     * The comparator to use when comparing two non-<code>null</code> objects.
-+     */
-+    private Comparator<T> nonNullComparator;
-+
-+    /**
-+     * Specifies whether a <code>null</code> are compared as higher than
-+     * non-<code>null</code> objects.
-+     */
-+    private boolean nullsAreHigh;
-+
-+    /**
-+     * Construct an instance that sorts <code>null</code> higher than any
-+     * non-<code>null</code> object it is compared with.  When comparing two
-+     * non-<code>null</code> objects, the specified {@link Comparator} is
-+     * used.
-+     *
-+     * @param nonNullComparator the comparator to use when comparing two
-+     *                          non-<code>null</code> objects.  This argument cannot be
-+     *                          <code>null</code>
-+     * @throws NullPointerException if <code>nonNullComparator</code> is
-+     *                              <code>null</code>
-+     */
-+    public NullComparator(Comparator<T> nonNullComparator) {
-+        this(nonNullComparator, true);
-+    }
-+
-+    /**
-+     * Construct an instance that sorts <code>null</code> higher or lower than
-+     * any non-<code>null</code> object it is compared with.  When comparing
-+     * two non-<code>null</code> objects, the specified {@link Comparator} is
-+     * used.
-+     *
-+     * @param nonNullComparator the comparator to use when comparing two
-+     *                          non-<code>null</code> objects. This argument cannot be
-+     *                          <code>null</code>
-+     * @param nullsAreHigh      a <code>true</code> value indicates that
-+     *                          <code>null</code> should be compared as higher than a
-+     *                          non-<code>null</code> object.  A <code>false</code> value indicates
-+     *                          that <code>null</code> should be compared as lower than a
-+     *                          non-<code>null</code> object.
-+     * @throws NullPointerException if <code>nonNullComparator</code> is
-+     *                              <code>null</code>
-+     */
-+    public NullComparator(Comparator<T> nonNullComparator, boolean nullsAreHigh) {
-+        this.nonNullComparator = nonNullComparator;
-+        this.nullsAreHigh = nullsAreHigh;
-+
-+        if (nonNullComparator == null) {
-+            throw new NullPointerException("null nonNullComparator");
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Perform a comparison between two objects.  If both objects are
-+     * <code>null</code>, a <code>0</code> value is returned.  If one object
-+     * is <code>null</code> and the other is not, the result is determined on
-+     * whether the Comparator was constructed to have nulls as higher or lower
-+     * than other objects.  If neither object is <code>null</code>, an
-+     * underlying comparator specified in the constructor (or the default) is
-+     * used to compare the non-<code>null</code> objects.
-+     *
-+     * @param o1 the first object to compare
-+     * @param o2 the object to compare it to.
-+     * @return <code>-1</code> if <code>o1</code> is "lower" than (less than,
-+     *         before, etc.) <code>o2</code>; <code>1</code> if <code>o1</code> is
-+     *         "higher" than (greater than, after, etc.) <code>o2</code>; or
-+     *         <code>0</code> if <code>o1</code> and <code>o2</code> are equal.
-+     */
-+    public int compare(T o1, T o2) {
-+        if (o1 == o2) {
-+            return 0;
-+        }
-+        if (o1 == null) {
-+            return (this.nullsAreHigh ? 1 : -1);
-+        }
-+        if (o2 == null) {
-+            return (this.nullsAreHigh ? -1 : 1);
-+        }
-+        return this.nonNullComparator.compare(o1, o2);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implement a hash code for this comparator that is consistent with
-+     * {@link #equals(Object)}.
-+     *
-+     * @return a hash code for this comparator.
-+     */
-+    public int hashCode() {
-+        return (nullsAreHigh ? -1 : 1) * nonNullComparator.hashCode();
-+    }
-+
-+    /**
-+     * Determines whether the specified object represents a comparator that is
-+     * equal to this comparator.
-+     *
-+     * @param obj the object to compare this comparator with.
-+     * @return <code>true</code> if the specified object is a NullComparator
-+     *         with equivalent <code>null</code> comparison behavior
-+     *         (i.e. <code>null</code> high or low) and with equivalent underlying
-+     *         non-<code>null</code> object comparators.
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj == null) {
-+            return false;
-+        }
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (!obj.getClass().equals(this.getClass())) {
-+            return false;
-+        }
-+
-+        NullComparator other = (NullComparator) obj;
-+
-+        return ((this.nullsAreHigh == other.nullsAreHigh) && (this.nonNullComparator.equals(other.nonNullComparator)));
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/ReverseComparator.java
-@@ -0,0 +1,109 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.comparators;
-+
-+import java.io.Serializable;
-+import java.util.Comparator;
-+
-+/**
-+ * Reverses the order of another comparator by reversing the arguments
-+ * to its {@link #compare(Object, Object) compare} method.
-+ *
-+ * @author Henri Yandell
-+ * @author Matt Hall, John Watkinson, Michael A. Smith
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @see java.util.Collections#reverseOrder()
-+ * @since Commons Collections 2.0
-+ */
-+public class ReverseComparator <T> implements Comparator<T>, Serializable {
-+
-+    /**
-+     * Serialization version from Collections 2.0.
-+     */
-+    private static final long serialVersionUID = 2858887242028539265L;
-+
-+    /**
-+     * The comparator being decorated.
-+     */
-+    private Comparator<T> comparator;
-+
-+    /**
-+     * Creates a comparator that inverts the comparison
-+     * of the given comparator.  Pass in a {@link ComparableComparator}
-+     * for reversing the natural order, as per
-+     * {@link java.util.Collections#reverseOrder()}</b>.
-+     *
-+     * @param comparator Comparator to reverse
-+     */
-+    public ReverseComparator(Comparator<T> comparator) {
-+        this.comparator = comparator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares two objects in reverse order.
-+     *
-+     * @param obj1 the first object to compare
-+     * @param obj2 the second object to compare
-+     * @return negative if obj1 is less, positive if greater, zero if equal
-+     */
-+    public int compare(T obj1, T obj2) {
-+        return comparator.compare(obj2, obj1);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implement a hash code for this comparator that is consistent with
-+     * {@link #equals(Object) equals}.
-+     *
-+     * @return a suitable hash code
-+     * @since Commons Collections 3.0
-+     */
-+    public int hashCode() {
-+        return "ReverseComparator".hashCode() ^ comparator.hashCode();
-+    }
-+
-+    /**
-+     * Returns <code>true</code> iff <i>that</i> Object is
-+     * is a {@link Comparator} whose ordering is known to be
-+     * equivalent to mine.
-+     * <p/>
-+     * This implementation returns <code>true</code>
-+     * iff <code><i>object</i>.{@link Object#getClass() getClass()}</code>
-+     * equals <code>this.getClass()</code>, and the underlying
-+     * comparators are equal.
-+     * Subclasses may want to override this behavior to remain consistent
-+     * with the {@link Comparator#equals(Object) equals} contract.
-+     *
-+     * @param object the object to compare to
-+     * @return true if equal
-+     * @since Commons Collections 3.0
-+     */
-+    public boolean equals(Object object) {
-+        if (this == object) {
-+            return true;
-+        } else if (null == object) {
-+            return false;
-+        } else if (object.getClass().equals(this.getClass())) {
-+            ReverseComparator thatrc = (ReverseComparator) object;
-+            return comparator.equals(thatrc.comparator);
-+        } else {
-+            return false;
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/TransformingComparator.java
-@@ -0,0 +1,70 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.comparators;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.Comparator;
-+
-+/**
-+ * Decorates another Comparator with transformation behavior. That is, the
-+ * return value from the transform operation will be passed to the decorated
-+ * {@link Comparator#compare(Object,Object) compare} method.
-+ *
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:20 $
-+ * @see org.apache.commons.collections15.Transformer
-+ * @see org.apache.commons.collections15.comparators.ComparableComparator
-+ * @since Commons Collections 2.0 (?)
-+ */
-+public class TransformingComparator <I,O> implements Comparator<I> {
-+
-+    /**
-+     * The decorated comparator.
-+     */
-+    protected Comparator<O> decorated;
-+    /**
-+     * The transformer being used.
-+     */
-+    protected Transformer<I, O> transformer;
-+
-+    /**
-+     * Constructs an instance with the given Transformer and Comparator.
-+     *
-+     * @param transformer what will transform the arguments to <code>compare</code>
-+     * @param decorated   the decorated Comparator
-+     */
-+    public TransformingComparator(Transformer<I, O> transformer, Comparator<O> decorated) {
-+        this.decorated = decorated;
-+        this.transformer = transformer;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the result of comparing the values from the transform operation.
-+     *
-+     * @param obj1 the first object to transform then compare
-+     * @param obj2 the second object to transform then compare
-+     * @return negative if obj1 is less, positive if greater, zero if equal
-+     */
-+    public int compare(I obj1, I obj2) {
-+        O value1 = this.transformer.transform(obj1);
-+        O value2 = this.transformer.transform(obj2);
-+        return this.decorated.compare(value1, value2);
-+    }
-+
-+}
-+
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/comparators/package.html
-@@ -0,0 +1,26 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:20 pents90 Exp $ -->
-+ <!--
-+   Copyright 2002-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link java.util.Comparator Comparator} interface.
-+<p>
-+You may also consider using 
-+{@link org.apache.commons.collections.ComparatorUtils ComparatorUtils},
-+which is a single class that uses static methods to construct instances
-+of the classes in this package.
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/AllPredicate.java
-@@ -0,0 +1,108 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+
-+/**
-+ * Predicate implementation that returns true if all the predicates return true.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class AllPredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -3094696765038308799L;
-+
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T>[] iPredicates;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>all</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<? super T>[] predicates) {
-+        FunctorUtils.validateMin2(predicates);
-+        predicates = FunctorUtils.copy(predicates);
-+        return new AllPredicate<T>(predicates);
-+    }
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>all</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     */
-+    public static <T> Predicate<T> getInstance(Collection<Predicate<? super T>> predicates) {
-+        Predicate[] preds = FunctorUtils.<T>validate(predicates);
-+        return new AllPredicate<T>(preds);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicates the predicates to check, not cloned, not null
-+     */
-+    public AllPredicate(Predicate<? super T>[] predicates) {
-+        super();
-+        iPredicates = predicates;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if all predicates return true.
-+     *
-+     * @param object the input object
-+     * @return true if all decorated predicates return true
-+     */
-+    public boolean evaluate(T object) {
-+        for (int i = 0; i < iPredicates.length; i++) {
-+            if (iPredicates[i].evaluate(object) == false) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Gets the predicates, do not modify the array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return iPredicates;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/AndPredicate.java
-@@ -0,0 +1,94 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if both the predicates return true.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class AndPredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 4189014213763186912L;
-+
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T> iPredicate1;
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T> iPredicate2;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicate1 the first predicate to check, not null
-+     * @param predicate2 the second predicate to check, not null
-+     * @return the <code>and</code> predicate
-+     * @throws IllegalArgumentException if either predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        if (predicate1 == null || predicate2 == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        return new AndPredicate<T>(predicate1, predicate2);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate1 the first predicate to check, not null
-+     * @param predicate2 the second predicate to check, not null
-+     */
-+    public AndPredicate(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        super();
-+        iPredicate1 = predicate1;
-+        iPredicate2 = predicate2;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if both predicates return true.
-+     *
-+     * @param object the input object
-+     * @return true if both decorated predicates return true
-+     */
-+    public boolean evaluate(T object) {
-+        return (iPredicate1.evaluate(object) && iPredicate2.evaluate(object));
-+    }
-+
-+    /**
-+     * Gets the two predicates being decorated as an array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return new Predicate[]{iPredicate1, iPredicate2};
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/AnyPredicate.java
-@@ -0,0 +1,108 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+
-+/**
-+ * Predicate implementation that returns true if any of the predicates return true.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class AnyPredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7429999530934647542L;
-+
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T>[] iPredicates;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>any</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<? super T>[] predicates) {
-+        FunctorUtils.validateMin2(predicates);
-+        predicates = FunctorUtils.copy(predicates);
-+        return new AnyPredicate<T>(predicates);
-+    }
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>all</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     */
-+    public static <T> Predicate<T> getInstance(Collection<Predicate<? super T>> predicates) {
-+        Predicate[] preds = FunctorUtils.validate(predicates);
-+        return new AnyPredicate<T>(preds);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicates the predicates to check, not cloned, not null
-+     */
-+    public AnyPredicate(Predicate<? super T>[] predicates) {
-+        super();
-+        iPredicates = predicates;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if any predicate returns true.
-+     *
-+     * @param object the input object
-+     * @return true if any decorated predicate return true
-+     */
-+    public boolean evaluate(T object) {
-+        for (int i = 0; i < iPredicates.length; i++) {
-+            if (iPredicates[i].evaluate(object)) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Gets the predicates, do not modify the array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return iPredicates;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ChainedClosure.java
-@@ -0,0 +1,136 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Closure implementation that chains the specified closures together.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ChainedClosure <T> implements Closure<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -3520677225766901240L;
-+
-+    /**
-+     * The closures to call in turn
-+     */
-+    private final Closure<? super T>[] iClosures;
-+
-+    /**
-+     * Factory method that performs validation and copies the parameter array.
-+     *
-+     * @param closures the closures to chain, copied, no nulls
-+     * @return the <code>chained</code> closure
-+     * @throws IllegalArgumentException if the closures array is null
-+     * @throws IllegalArgumentException if any closure in the array is null
-+     */
-+    public static <T> Closure<T> getInstance(Closure<? super T>[] closures) {
-+        FunctorUtils.validate(closures);
-+        if (closures.length == 0) {
-+            return NOPClosure.INSTANCE;
-+        }
-+        closures = FunctorUtils.copy(closures);
-+        return new ChainedClosure<T>(closures);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls each closure in turn, passing the
-+     * result into the next closure. The ordering is that of the iterator()
-+     * method on the collection.
-+     *
-+     * @param closures a collection of closures to chain
-+     * @return the <code>chained</code> closure
-+     * @throws IllegalArgumentException if the closures collection is null
-+     * @throws IllegalArgumentException if any closure in the collection is null
-+     */
-+    public static <T> Closure<T> getInstance(Collection<? super T> closures) {
-+        if (closures == null) {
-+            throw new IllegalArgumentException("Closure collection must not be null");
-+        }
-+        if (closures.size() == 0) {
-+            return NOPClosure.INSTANCE;
-+        }
-+        // convert to array like this to guarantee iterator() ordering
-+        Closure<? super T>[] cmds = new Closure[closures.size()];
-+        int i = 0;
-+        for (Iterator it = closures.iterator(); it.hasNext();) {
-+            cmds[i++] = (Closure<? super T>) it.next();
-+        }
-+        FunctorUtils.validate(cmds);
-+        return new ChainedClosure(cmds);
-+    }
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param closure1 the first closure, not null
-+     * @param closure2 the second closure, not null
-+     * @return the <code>chained</code> closure
-+     * @throws IllegalArgumentException if either closure is null
-+     */
-+    public static <T> Closure<T> getInstance(Closure<? super T> closure1, Closure<? super T> closure2) {
-+        if (closure1 == null || closure2 == null) {
-+            throw new IllegalArgumentException("Closures must not be null");
-+        }
-+        Closure<? super T>[] closures = new Closure[]{closure1, closure2};
-+        return new ChainedClosure<T>(closures);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param closures the closures to chain, not copied, no nulls
-+     */
-+    public ChainedClosure(Closure<? super T>[] closures) {
-+        super();
-+        iClosures = closures;
-+    }
-+
-+    /**
-+     * Execute a list of closures.
-+     *
-+     * @param input the input object passed to each closure
-+     */
-+    public void execute(T input) {
-+        for (int i = 0; i < iClosures.length; i++) {
-+            iClosures[i].execute(input);
-+        }
-+    }
-+
-+    /**
-+     * Gets the closures, do not modify the array.
-+     *
-+     * @return the closures
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<? super T>[] getClosures() {
-+        return iClosures;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ChainedTransformer.java
-@@ -0,0 +1,142 @@
-+// GenericsNote: Converted, but only partially type-safe.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Transformer implementation that chains the specified transformers together.
-+ * <p/>
-+ * The input object is passed to the first transformer. The transformed result
-+ * is passed to the second transformer and so on.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ChainedTransformer <I,O> implements Transformer<I, O>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 3514945074733160196L;
-+
-+    /**
-+     * The transformers to call in turn
-+     */
-+    private final Transformer[] iTransformers;
-+
-+    /**
-+     * Factory method that performs validation and copies the parameter array.
-+     *
-+     * @param transformers the transformers to chain, copied, no nulls
-+     * @return the <code>chained</code> transformer
-+     * @throws IllegalArgumentException if the transformers array is null
-+     * @throws IllegalArgumentException if any transformer in the array is null
-+     */
-+    public static <I,O> Transformer<I, O> getInstance(Transformer[] transformers) {
-+        FunctorUtils.validate(transformers);
-+        if (transformers.length == 0) {
-+            return NOPTransformer.INSTANCE;
-+        }
-+        transformers = FunctorUtils.copy(transformers);
-+        return new ChainedTransformer<I, O>(transformers);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls each transformer in turn, passing the
-+     * result into the next transformer. The ordering is that of the iterator()
-+     * method on the collection.
-+     *
-+     * @param transformers a collection of transformers to chain
-+     * @return the <code>chained</code> transformer
-+     * @throws IllegalArgumentException if the transformers collection is null
-+     * @throws IllegalArgumentException if any transformer in the collection is null
-+     */
-+    public static <I,O> Transformer<I, O> getInstance(Collection<Transformer> transformers) {
-+        if (transformers == null) {
-+            throw new IllegalArgumentException("Transformer collection must not be null");
-+        }
-+        if (transformers.size() == 0) {
-+            return NOPTransformer.INSTANCE;
-+        }
-+        // convert to array like this to guarantee iterator() ordering
-+        Transformer[] cmds = new Transformer[transformers.size()];
-+        int i = 0;
-+        for (Iterator<Transformer> it = transformers.iterator(); it.hasNext();) {
-+            cmds[i++] = it.next();
-+        }
-+        FunctorUtils.validate(cmds);
-+        return new ChainedTransformer<I, O>(cmds);
-+    }
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param transformer1 the first transformer, not null
-+     * @param transformer2 the second transformer, not null
-+     * @return the <code>chained</code> transformer
-+     * @throws IllegalArgumentException if either transformer is null
-+     */
-+    public static <I,M,O> Transformer<I, O> getInstance(Transformer<I, ? extends M> transformer1, Transformer<? super M, O> transformer2) {
-+        if (transformer1 == null || transformer2 == null) {
-+            throw new IllegalArgumentException("Transformers must not be null");
-+        }
-+        Transformer[] transformers = new Transformer[]{transformer1, transformer2};
-+        return new ChainedTransformer<I, O>(transformers);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param transformers the transformers to chain, not copied, no nulls
-+     */
-+    public ChainedTransformer(Transformer[] transformers) {
-+        super();
-+        iTransformers = transformers;
-+    }
-+
-+    /**
-+     * Transforms the input to result via each decorated transformer
-+     *
-+     * @param object the input object passed to the first transformer
-+     * @return the transformed result
-+     */
-+    public O transform(I object) {
-+        Object intermediate = object;
-+        for (int i = 0; i < iTransformers.length; i++) {
-+            intermediate = iTransformers[i].transform(intermediate);
-+        }
-+        return (O) intermediate;
-+    }
-+
-+    /**
-+     * Gets the transformers, do not modify the array.
-+     *
-+     * @return the transformers
-+     * @since Commons Collections 3.1
-+     */
-+    public Transformer[] getTransformers() {
-+        return iTransformers;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/CloneTransformer.java
-@@ -0,0 +1,74 @@
-+// GenericsNote: Converted (nothing to convert).
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that returns a clone of the input object.
-+ * <p/>
-+ * Clone is performed using <code>PrototypeFactory.getInstance(input).create()</code>.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class CloneTransformer<T> implements Transformer<T,T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -8188742709499652567L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Transformer INSTANCE = new CloneTransformer();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+	public static <T> Transformer<T,T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Constructor
-+     */
-+    private CloneTransformer() {
-+        super();
-+    }
-+
-+    /**
-+     * Transforms the input to result by cloning it.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public T transform(T input) {
-+        if (input == null) {
-+            return null;
-+        }
-+        return PrototypeFactory.getInstance(input).create();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ClosureTransformer.java
-@@ -0,0 +1,90 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that calls a Closure using the input object
-+ * and then returns the input.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ClosureTransformer <T> implements Transformer<T, T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 478466901448617286L;
-+
-+    /**
-+     * The closure to wrap
-+     */
-+    private final Closure<T> iClosure;
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param closure the closure to call, not null
-+     * @return the <code>closure</code> transformer
-+     * @throws IllegalArgumentException if the closure is null
-+     */
-+    public static <T> Transformer<T, T> getInstance(Closure<T> closure) {
-+        if (closure == null) {
-+            throw new IllegalArgumentException("Closure must not be null");
-+        }
-+        return new ClosureTransformer<T>(closure);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param closure the closure to call, not null
-+     */
-+    public ClosureTransformer(Closure<T> closure) {
-+        super();
-+        iClosure = closure;
-+    }
-+
-+    /**
-+     * Transforms the input to result by executing a closure.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public T transform(T input) {
-+        iClosure.execute(input);
-+        return input;
-+    }
-+
-+    /**
-+     * Gets the closure.
-+     *
-+     * @return the closure
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<T> getClosure() {
-+        return iClosure;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ConstantFactory.java
-@@ -0,0 +1,94 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Factory;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Factory implementation that returns the same constant each time.
-+ * <p/>
-+ * No check is made that the object is immutable. In general, only immutable
-+ * objects should use the constant factory. Mutable objects should
-+ * use the prototype factory.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ConstantFactory <T> implements Factory<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -3520677225766901240L;
-+
-+    /**
-+     * Returns null each time
-+     */
-+    public static final Factory NULL_INSTANCE = new ConstantFactory(null);
-+
-+    /**
-+     * The closures to call in turn
-+     */
-+    private final T iConstant;
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param constantToReturn the constant object to return each time in the factory
-+     * @return the <code>constant</code> factory.
-+     */
-+    public static <T> Factory<T> getInstance(T constantToReturn) {
-+        if (constantToReturn == null) {
-+            return NULL_INSTANCE;
-+        }
-+        return new ConstantFactory<T>(constantToReturn);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param constantToReturn the constant to return each time
-+     */
-+    public ConstantFactory(T constantToReturn) {
-+        super();
-+        iConstant = constantToReturn;
-+    }
-+
-+    /**
-+     * Always return constant.
-+     *
-+     * @return the stored constant value
-+     */
-+    public T create() {
-+        return iConstant;
-+    }
-+
-+    /**
-+     * Gets the constant.
-+     *
-+     * @return the constant
-+     * @since Commons Collections 3.1
-+     */
-+    public T getConstant() {
-+        return iConstant;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ConstantTransformer.java
-@@ -0,0 +1,95 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that returns the same constant each time.
-+ * <p/>
-+ * No check is made that the object is immutable. In general, only immutable
-+ * objects should use the constant factory. Mutable objects should
-+ * use the prototype factory.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ConstantTransformer <T> implements Transformer<Object, T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 6374440726369055124L;
-+
-+    /**
-+     * Returns null each time
-+     */
-+    public static final Transformer NULL_INSTANCE = new ConstantTransformer(null);
-+
-+    /**
-+     * The closures to call in turn
-+     */
-+    private final T iConstant;
-+
-+    /**
-+     * Transformer method that performs validation.
-+     *
-+     * @param constantToReturn the constant object to return each time in the factory
-+     * @return the <code>constant</code> factory.
-+     */
-+    public static <T> Transformer<Object, T> getInstance(T constantToReturn) {
-+        if (constantToReturn == null) {
-+            return NULL_INSTANCE;
-+        }
-+        return new ConstantTransformer<T>(constantToReturn);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param constantToReturn the constant to return each time
-+     */
-+    public ConstantTransformer(T constantToReturn) {
-+        super();
-+        iConstant = constantToReturn;
-+    }
-+
-+    /**
-+     * Transforms the input by ignoring it and returning the stored constant instead.
-+     *
-+     * @param input the input object which is ignored
-+     * @return the stored constant
-+     */
-+    public T transform(Object input) {
-+        return iConstant;
-+    }
-+
-+    /**
-+     * Gets the constant.
-+     *
-+     * @return the constant
-+     * @since Commons Collections 3.1
-+     */
-+    public T getConstant() {
-+        return iConstant;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/EqualPredicate.java
-@@ -0,0 +1,88 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if the input is the same object
-+ * as the one stored in this predicate by equals.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class EqualPredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 5633766978029907089L;
-+
-+    /**
-+     * The value to compare to
-+     */
-+    private final T iValue;
-+
-+    /**
-+     * Factory to create the identity predicate.
-+     *
-+     * @param object the object to compare to
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(T object) {
-+        if (object == null) {
-+            return NullPredicate.INSTANCE;
-+        }
-+        return new EqualPredicate<T>(object);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param object the object to compare to
-+     */
-+    public EqualPredicate(T object) {
-+        super();
-+        iValue = object;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if the input equals the stored value.
-+     *
-+     * @param object the input object
-+     * @return true if input object equals stored value
-+     */
-+    public boolean evaluate(T object) {
-+        return (iValue.equals(object));
-+    }
-+
-+    /**
-+     * Gets the value.
-+     *
-+     * @return the value
-+     * @since Commons Collections 3.1
-+     */
-+    public T getValue() {
-+        return iValue;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ExceptionClosure.java
-@@ -0,0 +1,71 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+import org.apache.commons.collections15.FunctorException;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Closure implementation that always throws an exception.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class ExceptionClosure <T> implements Closure<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7179106032121985545L;
-+
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Closure INSTANCE = new ExceptionClosure();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+	public static <T> Closure<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private ExceptionClosure() {
-+        super();
-+    }
-+
-+    /**
-+     * Always throw an exception.
-+     *
-+     * @param input the input object
-+     * @throws FunctorException always
-+     */
-+    public void execute(T input) {
-+        throw new FunctorException("ExceptionClosure invoked");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ExceptionFactory.java
-@@ -0,0 +1,71 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Factory;
-+import org.apache.commons.collections15.FunctorException;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Factory implementation that always throws an exception.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class ExceptionFactory <T> implements Factory<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7179106032121985545L;
-+
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Factory INSTANCE = new ExceptionFactory();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+	public static <T> Factory<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private ExceptionFactory() {
-+        super();
-+    }
-+
-+    /**
-+     * Always throws an exception.
-+     *
-+     * @return never
-+     * @throws FunctorException always
-+     */
-+    public T create() {
-+        throw new FunctorException("ExceptionFactory invoked");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ExceptionPredicate.java
-@@ -0,0 +1,71 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.FunctorException;
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that always throws an exception.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class ExceptionPredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7179106032121985545L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Predicate INSTANCE = new ExceptionPredicate();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+	public static <T> Predicate<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private ExceptionPredicate() {
-+        super();
-+    }
-+
-+    /**
-+     * Evaluates the predicate always throwing an exception.
-+     *
-+     * @param object the input object
-+     * @return never
-+     * @throws FunctorException always
-+     */
-+    public boolean evaluate(T object) {
-+        throw new FunctorException("ExceptionPredicate invoked");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ExceptionTransformer.java
-@@ -0,0 +1,72 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.FunctorException;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that always throws an exception.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class ExceptionTransformer <I,O> implements Transformer<I, O>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7179106032121985545L;
-+
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Transformer INSTANCE = new ExceptionTransformer();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+	public static <I,O> Transformer<I,O> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private ExceptionTransformer() {
-+        super();
-+    }
-+
-+    /**
-+     * Transforms the input to result by cloning it.
-+     *
-+     * @param input the input object to transform
-+     * @return never
-+     * @throws FunctorException always
-+     */
-+    public O transform(I input) {
-+        throw new FunctorException("ExceptionTransformer invoked");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/FactoryTransformer.java
-@@ -0,0 +1,89 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Factory;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that calls a Factory and returns the result.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class FactoryTransformer <I, T> implements Transformer<I, T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -6817674502475353160L;
-+
-+    /**
-+     * The factory to wrap
-+     */
-+    private final Factory<T> iFactory;
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param factory the factory to call, not null
-+     * @return the <code>factory</code> transformer
-+     * @throws IllegalArgumentException if the factory is null
-+     */
-+    public static <K,T> Transformer<K, T> getInstance(Factory<T> factory) {
-+        if (factory == null) {
-+            throw new IllegalArgumentException("Factory must not be null");
-+        }
-+        return new FactoryTransformer<K, T>(factory);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param factory the factory to call, not null
-+     */
-+    public FactoryTransformer(Factory<T> factory) {
-+        super();
-+        iFactory = factory;
-+    }
-+
-+    /**
-+     * Transforms the input by ignoring the input and returning the result of
-+     * calling the decorated factory.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public T transform(I input) {
-+        return iFactory.create();
-+    }
-+
-+    /**
-+     * Gets the factory.
-+     *
-+     * @return the factory
-+     * @since Commons Collections 3.1
-+     */
-+    public Factory<T> getFactory() {
-+        return iFactory;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/FalsePredicate.java
-@@ -0,0 +1,69 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that always returns false.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class FalsePredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7533784454832764388L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Predicate INSTANCE = new FalsePredicate();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+    public static <T> Predicate<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private FalsePredicate() {
-+        super();
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning false always.
-+     *
-+     * @param object the input object
-+     * @return false always
-+     */
-+    public boolean evaluate(T object) {
-+        return false;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/ForClosure.java
-@@ -0,0 +1,110 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Closure implementation that calls another closure n times, like a for loop.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ForClosure <T> implements Closure<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -1190120533393621674L;
-+
-+    /**
-+     * The number of times to loop
-+     */
-+    private final int iCount;
-+    /**
-+     * The closure to call
-+     */
-+    private final Closure<T> iClosure;
-+
-+    /**
-+     * Factory method that performs validation.
-+     * <p/>
-+     * A null closure or zero count returns the <code>NOPClosure</code>.
-+     * A count of one returns the specified closure.
-+     *
-+     * @param count   the number of times to execute the closure
-+     * @param closure the closure to execute, not null
-+     * @return the <code>for</code> closure
-+     */
-+    public static <T> Closure<T> getInstance(int count, Closure<T> closure) {
-+        if (count <= 0 || closure == null) {
-+            return NOPClosure.INSTANCE;
-+        }
-+        if (count == 1) {
-+            return closure;
-+        }
-+        return new ForClosure<T>(count, closure);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param count   the number of times to execute the closure
-+     * @param closure the closure to execute, not null
-+     */
-+    public ForClosure(int count, Closure<T> closure) {
-+        super();
-+        iCount = count;
-+        iClosure = closure;
-+    }
-+
-+    /**
-+     * Executes the closure <code>count</code> times.
-+     *
-+     * @param input the input object
-+     */
-+    public void execute(T input) {
-+        for (int i = 0; i < iCount; i++) {
-+            iClosure.execute(input);
-+        }
-+    }
-+
-+    /**
-+     * Gets the closure.
-+     *
-+     * @return the closure
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<T> getClosure() {
-+        return iClosure;
-+    }
-+
-+    /**
-+     * Gets the count.
-+     *
-+     * @return the count
-+     * @since Commons Collections 3.1
-+     */
-+    public int getCount() {
-+        return iCount;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/FunctorUtils.java
-@@ -0,0 +1,174 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+
-+/**
-+ * Internal utilities for functors.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+class FunctorUtils {
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private FunctorUtils() {
-+        super();
-+    }
-+
-+    /**
-+     * Clone the predicates to ensure that the internal reference can't be messed with.
-+     *
-+     * @param predicates the predicates to copy
-+     * @return the cloned predicates
-+     */
-+    static <T> Predicate<? super T>[] copy(Predicate<? super T>[] predicates) {
-+        if (predicates == null) {
-+            return null;
-+        }
-+        return (Predicate<? super T>[]) predicates.clone();
-+    }
-+
-+    /**
-+     * Validate the predicates to ensure that all is well.
-+     *
-+     * @param predicates the predicates to validate
-+     */
-+    static <T> void validate(Predicate<? super T>[] predicates) {
-+        if (predicates == null) {
-+            throw new IllegalArgumentException("The predicate array must not be null");
-+        }
-+        for (int i = 0; i < predicates.length; i++) {
-+            if (predicates[i] == null) {
-+                throw new IllegalArgumentException("The predicate array must not contain a null predicate, index " + i + " was null");
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Validate the predicates to ensure that all is well.
-+     *
-+     * @param predicates the predicates to validate
-+     */
-+    static <T> void validateMin2(Predicate<? super T>[] predicates) {
-+        if (predicates == null) {
-+            throw new IllegalArgumentException("The predicate array must not be null");
-+        }
-+        if (predicates.length < 2) {
-+            throw new IllegalArgumentException("At least 2 predicates must be specified in the predicate array, size was " + predicates.length);
-+        }
-+        for (int i = 0; i < predicates.length; i++) {
-+            if (predicates[i] == null) {
-+                throw new IllegalArgumentException("The predicate array must not contain a null predicate, index " + i + " was null");
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Validate the predicates to ensure that all is well.
-+     *
-+     * @param predicates the predicates to validate
-+     * @return predicate array
-+     */
-+    static <T> Predicate<? super T>[] validate(Collection<Predicate<? super T>> predicates) {
-+        if (predicates == null) {
-+            throw new IllegalArgumentException("The predicate collection must not be null");
-+        }
-+        if (predicates.size() < 2) {
-+            throw new IllegalArgumentException("At least 2 predicates must be specified in the predicate collection, size was " + predicates.size());
-+        }
-+        // convert to array like this to guarantee iterator() ordering
-+        Predicate<? super T>[] preds = new Predicate[predicates.size()];
-+        int i = 0;
-+        for (Iterator<Predicate<? super T>> it = predicates.iterator(); it.hasNext();) {
-+            preds[i] = it.next();
-+            if (preds[i] == null) {
-+                throw new IllegalArgumentException("The predicate collection must not contain a null predicate, index " + i + " was null");
-+            }
-+            i++;
-+        }
-+        return preds;
-+    }
-+
-+    /**
-+     * Clone the closures to ensure that the internal reference can't be messed with.
-+     *
-+     * @param closures the closures to copy
-+     * @return the cloned closures
-+     */
-+    static <T> Closure<? super T>[] copy(Closure<? super T>[] closures) {
-+        if (closures == null) {
-+            return null;
-+        }
-+        return (Closure<? super T>[]) closures.clone();
-+    }
-+
-+    /**
-+     * Validate the closures to ensure that all is well.
-+     *
-+     * @param closures the closures to validate
-+     */
-+    static <T> void validate(Closure<? super T>[] closures) {
-+        if (closures == null) {
-+            throw new IllegalArgumentException("The closure array must not be null");
-+        }
-+        for (int i = 0; i < closures.length; i++) {
-+            if (closures[i] == null) {
-+                throw new IllegalArgumentException("The closure array must not contain a null closure, index " + i + " was null");
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Copy method
-+     *
-+     * @param transformers the transformers to copy
-+     * @return a clone of the transformers
-+     */
-+    static <I,O> Transformer<? super I, ? extends O>[] copy(Transformer<? super I, ? extends O>[] transformers) {
-+        if (transformers == null) {
-+            return null;
-+        }
-+        return (Transformer<? super I, ? extends O>[]) transformers.clone();
-+    }
-+
-+    /**
-+     * Validate method
-+     *
-+     * @param transformers the transformers to validate
-+     */
-+    static <I,O> void validate(Transformer<? super I, ? extends O>[] transformers) {
-+        if (transformers == null) {
-+            throw new IllegalArgumentException("The transformer array must not be null");
-+        }
-+        for (int i = 0; i < transformers.length; i++) {
-+            if (transformers[i] == null) {
-+                throw new IllegalArgumentException("The transformer array must not contain a null transformer, index " + i + " was null");
-+            }
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/IdentityPredicate.java
-@@ -0,0 +1,90 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if the input is the same object
-+ * as the one stored in this predicate.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class IdentityPredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -89901658494523293L;
-+
-+
-+    /**
-+     * The value to compare to
-+     */
-+    private final T iValue;
-+
-+    /**
-+     * Factory to create the identity predicate.
-+     *
-+     * @param object the object to compare to
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(T object) {
-+        if (object == null) {
-+            return NullPredicate.INSTANCE;
-+        }
-+        return new IdentityPredicate<T>(object);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param object the object to compare to
-+     */
-+    public IdentityPredicate(T object) {
-+        super();
-+        iValue = object;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if the input object is identical to
-+     * the stored object.
-+     *
-+     * @param object the input object
-+     * @return true if input is the same object as the stored value
-+     */
-+    public boolean evaluate(T object) {
-+        return (iValue == object);
-+    }
-+
-+    /**
-+     * Gets the value.
-+     *
-+     * @return the value
-+     * @since Commons Collections 3.1
-+     */
-+    public T getValue() {
-+        return iValue;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/IfClosure.java
-@@ -0,0 +1,129 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Closure implementation acts as an if statement calling one or other closure
-+ * based on a predicate.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class IfClosure <T> implements Closure<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 3518477308466486130L;
-+
-+    /**
-+     * The test
-+     */
-+    private final Predicate<? super T> iPredicate;
-+    /**
-+     * The closure to use if true
-+     */
-+    private final Closure<? super T> iTrueClosure;
-+    /**
-+     * The closure to use if false
-+     */
-+    private final Closure<? super T> iFalseClosure;
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param predicate    predicate to switch on
-+     * @param trueClosure  closure used if true
-+     * @param falseClosure closure used if false
-+     * @return the <code>if</code> closure
-+     * @throws IllegalArgumentException if any argument is null
-+     */
-+    public static <T> Closure<T> getInstance(Predicate<? super T> predicate, Closure<? super T> trueClosure, Closure<? super T> falseClosure) {
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        if (trueClosure == null || falseClosure == null) {
-+            throw new IllegalArgumentException("Closures must not be null");
-+        }
-+        return new IfClosure<T>(predicate, trueClosure, falseClosure);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate    predicate to switch on, not null
-+     * @param trueClosure  closure used if true, not null
-+     * @param falseClosure closure used if false, not null
-+     */
-+    public IfClosure(Predicate<? super T> predicate, Closure<? super T> trueClosure, Closure<? super T> falseClosure) {
-+        super();
-+        iPredicate = predicate;
-+        iTrueClosure = trueClosure;
-+        iFalseClosure = falseClosure;
-+    }
-+
-+    /**
-+     * Executes the true or false closure accoring to the result of the predicate.
-+     *
-+     * @param input the input object
-+     */
-+    public void execute(T input) {
-+        if (iPredicate.evaluate(input) == true) {
-+            iTrueClosure.execute(input);
-+        } else {
-+            iFalseClosure.execute(input);
-+        }
-+    }
-+
-+    /**
-+     * Gets the predicate.
-+     *
-+     * @return the predicate
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T> getPredicate() {
-+        return iPredicate;
-+    }
-+
-+    /**
-+     * Gets the closure called when true.
-+     *
-+     * @return the closure
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<? super T> getTrueClosure() {
-+        return iTrueClosure;
-+    }
-+
-+    /**
-+     * Gets the closure called when false.
-+     *
-+     * @return the closure
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<? super T> getFalseClosure() {
-+        return iFalseClosure;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/InstanceofPredicate.java
-@@ -0,0 +1,90 @@
-+// GenericsNote: Converted, although perhaps this should not be templated. Not sure!
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if the input is an instanceof
-+ * the type stored in this predicate.
-+ *
-+ * Since this predicate operates on the type of the objects passed to it, generics are not used.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class InstanceofPredicate implements Predicate, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -6682656911025165584L;
-+
-+    /**
-+     * The type to compare to
-+     */
-+    private final Class iType;
-+
-+    /**
-+     * Factory to create the identity predicate.
-+     *
-+     * @param type the type to check for, may not be null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the class is null
-+     */
-+    public static Predicate getInstance(Class type) {
-+        if (type == null) {
-+            throw new IllegalArgumentException("The type to check instanceof must not be null");
-+        }
-+        return new InstanceofPredicate(type);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param type the type to check for
-+     */
-+    public InstanceofPredicate(Class type) {
-+        super();
-+        iType = type;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if the input object is of the correct type.
-+     *
-+     * @param object the input object
-+     * @return true if input is of stored type
-+     */
-+    public boolean evaluate(Object object) {
-+        return (iType.isInstance(object));
-+    }
-+
-+    /**
-+     * Gets the type to compare to.
-+     *
-+     * @return the type
-+     * @since Commons Collections 3.1
-+     */
-+    public Class getType() {
-+        return iType;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/InstantiateFactory.java
-@@ -0,0 +1,147 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Factory;
-+import org.apache.commons.collections15.FunctorException;
-+
-+import java.io.Serializable;
-+import java.lang.reflect.Constructor;
-+import java.lang.reflect.InvocationTargetException;
-+
-+/**
-+ * Factory implementation that creates a new object instance by reflection.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class InstantiateFactory <T> implements Factory<T>, Serializable {
-+
-+    /**
-+     * The serial version
-+     */
-+    static final long serialVersionUID = -7732226881069447957L;
-+
-+    /**
-+     * The class to create
-+     */
-+    private final Class<T> iClassToInstantiate;
-+    /**
-+     * The constructor parameter types
-+     */
-+    private final Class[] iParamTypes;
-+    /**
-+     * The constructor arguments
-+     */
-+    private final Object[] iArgs;
-+    /**
-+     * The constructor
-+     */
-+    private transient Constructor iConstructor = null;
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param classToInstantiate the class to instantiate, not null
-+     * @param paramTypes         the constructor parameter types
-+     * @param args               the constructor arguments
-+     * @return a new instantiate factory
-+     */
-+    public static <T> Factory<T> getInstance(Class<T> classToInstantiate, Class[] paramTypes, Object[] args) {
-+        if (classToInstantiate == null) {
-+            throw new IllegalArgumentException("Class to instantiate must not be null");
-+        }
-+        if (((paramTypes == null) && (args != null)) || ((paramTypes != null) && (args == null)) || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
-+            throw new IllegalArgumentException("Parameter types must match the arguments");
-+        }
-+
-+        if (paramTypes == null || paramTypes.length == 0) {
-+            return new InstantiateFactory<T>(classToInstantiate);
-+        } else {
-+            paramTypes = (Class[]) paramTypes.clone();
-+            args = (Object[]) args.clone();
-+            return new InstantiateFactory<T>(classToInstantiate, paramTypes, args);
-+        }
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param classToInstantiate the class to instantiate
-+     */
-+    public InstantiateFactory(Class<T> classToInstantiate) {
-+        super();
-+        iClassToInstantiate = classToInstantiate;
-+        iParamTypes = null;
-+        iArgs = null;
-+        findConstructor();
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param classToInstantiate the class to instantiate
-+     * @param paramTypes         the constructor parameter types, not cloned
-+     * @param args               the constructor arguments, not cloned
-+     */
-+    public InstantiateFactory(Class<T> classToInstantiate, Class[] paramTypes, Object[] args) {
-+        super();
-+        iClassToInstantiate = classToInstantiate;
-+        iParamTypes = paramTypes;
-+        iArgs = args;
-+        findConstructor();
-+    }
-+
-+    /**
-+     * Find the Constructor for the class specified.
-+     */
-+    private void findConstructor() {
-+        try {
-+            iConstructor = iClassToInstantiate.getConstructor(iParamTypes);
-+
-+        } catch (NoSuchMethodException ex) {
-+            throw new IllegalArgumentException("InstantiateFactory: The constructor must exist and be public ");
-+        }
-+    }
-+
-+    /**
-+     * Creates an object using the stored constructor.
-+     *
-+     * @return the new object
-+     */
-+    public T create() {
-+        // needed for post-serialization
-+        if (iConstructor == null) {
-+            findConstructor();
-+        }
-+
-+        try {
-+            return (T) iConstructor.newInstance(iArgs);
-+
-+        } catch (InstantiationException ex) {
-+            throw new FunctorException("InstantiateFactory: InstantiationException", ex);
-+        } catch (IllegalAccessException ex) {
-+            throw new FunctorException("InstantiateFactory: Constructor must be public", ex);
-+        } catch (InvocationTargetException ex) {
-+            throw new FunctorException("InstantiateFactory: Constructor threw an exception", ex);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/InstantiateTransformer.java
-@@ -0,0 +1,119 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.FunctorException;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+import java.lang.reflect.Constructor;
-+import java.lang.reflect.InvocationTargetException;
-+
-+/**
-+ * Transformer implementation that creates a new object instance by reflection.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class InstantiateTransformer implements Transformer<Class, Object>, Serializable {
-+
-+    /**
-+     * The serial version
-+     */
-+    static final long serialVersionUID = 3786388740793356347L;
-+
-+    /**
-+     * Singleton instance that uses the no arg constructor
-+     */
-+    public static final InstantiateTransformer NO_ARG_INSTANCE = new InstantiateTransformer();
-+
-+    /**
-+     * The constructor parameter types
-+     */
-+    private final Class[] iParamTypes;
-+    /**
-+     * The constructor arguments
-+     */
-+    private final Object[] iArgs;
-+
-+    /**
-+     * Transformer method that performs validation.
-+     *
-+     * @param paramTypes the constructor parameter types
-+     * @param args       the constructor arguments
-+     * @return an instantiate transformer
-+     */
-+    public static InstantiateTransformer getInstance(Class[] paramTypes, Object[] args) {
-+        if (((paramTypes == null) && (args != null)) || ((paramTypes != null) && (args == null)) || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
-+            throw new IllegalArgumentException("Parameter types must match the arguments");
-+        }
-+
-+        if (paramTypes == null || paramTypes.length == 0) {
-+            return NO_ARG_INSTANCE;
-+        } else {
-+            paramTypes = (Class[]) paramTypes.clone();
-+            args = (Object[]) args.clone();
-+        }
-+        return new InstantiateTransformer(paramTypes, args);
-+    }
-+
-+    /**
-+     * Constructor for no arg instance.
-+     */
-+    private InstantiateTransformer() {
-+        super();
-+        iParamTypes = null;
-+        iArgs = null;
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param paramTypes the constructor parameter types, not cloned
-+     * @param args       the constructor arguments, not cloned
-+     */
-+    public InstantiateTransformer(Class[] paramTypes, Object[] args) {
-+        super();
-+        iParamTypes = paramTypes;
-+        iArgs = args;
-+    }
-+
-+    /**
-+     * Transforms the input Class object to a result by instantiation.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public Object transform(Class input) {
-+        try {
-+            Constructor con = ((Class) input).getConstructor(iParamTypes);
-+            return con.newInstance(iArgs);
-+
-+        } catch (NoSuchMethodException ex) {
-+            throw new FunctorException("InstantiateTransformer: The constructor must exist and be public ");
-+        } catch (InstantiationException ex) {
-+            throw new FunctorException("InstantiateTransformer: InstantiationException", ex);
-+        } catch (IllegalAccessException ex) {
-+            throw new FunctorException("InstantiateTransformer: Constructor must be public", ex);
-+        } catch (InvocationTargetException ex) {
-+            throw new FunctorException("InstantiateTransformer: Constructor threw an exception", ex);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/InvokerTransformer.java
-@@ -0,0 +1,142 @@
-+// GenericsNote: Converted (nothing to convert).
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.FunctorException;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+import java.lang.reflect.InvocationTargetException;
-+import java.lang.reflect.Method;
-+
-+/**
-+ * Transformer implementation that creates a new object instance by reflection.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class InvokerTransformer implements Transformer, Serializable {
-+
-+    /**
-+     * The serial version
-+     */
-+    static final long serialVersionUID = -8653385846894047688L;
-+
-+    /**
-+     * The method name to call
-+     */
-+    private final String iMethodName;
-+    /**
-+     * The array of reflection parameter types
-+     */
-+    private final Class[] iParamTypes;
-+    /**
-+     * The array of reflection arguments
-+     */
-+    private final Object[] iArgs;
-+
-+    /**
-+     * Gets an instance of this transformer calling a specific method with no arguments.
-+     *
-+     * @param methodName the method name to call
-+     * @return an invoker transformer
-+     * @since Commons Collections 3.1
-+     */
-+    public static Transformer getInstance(String methodName) {
-+        if (methodName == null) {
-+            throw new IllegalArgumentException("The method to invoke must not be null");
-+        }
-+        return new InvokerTransformer(methodName);
-+    }
-+
-+    /**
-+     * Gets an instance of this transformer calling a specific method with specific values.
-+     *
-+     * @param methodName the method name to call
-+     * @param paramTypes the parameter types of the method
-+     * @param args       the arguments to pass to the method
-+     * @return an invoker transformer
-+     */
-+    public static Transformer getInstance(String methodName, Class[] paramTypes, Object[] args) {
-+        if (methodName == null) {
-+            throw new IllegalArgumentException("The method to invoke must not be null");
-+        }
-+        if (((paramTypes == null) && (args != null)) || ((paramTypes != null) && (args == null)) || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
-+            throw new IllegalArgumentException("The parameter types must match the arguments");
-+        }
-+        if (paramTypes == null || paramTypes.length == 0) {
-+            return new InvokerTransformer(methodName);
-+        } else {
-+            paramTypes = (Class[]) paramTypes.clone();
-+            args = (Object[]) args.clone();
-+            return new InvokerTransformer(methodName, paramTypes, args);
-+        }
-+    }
-+
-+    /**
-+     * Constructor for no arg instance.
-+     *
-+     * @param methodName the method to call
-+     */
-+    private InvokerTransformer(String methodName) {
-+        super();
-+        iMethodName = methodName;
-+        iParamTypes = null;
-+        iArgs = null;
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param methodName the method to call
-+     * @param paramTypes the constructor parameter types, not cloned
-+     * @param args       the constructor arguments, not cloned
-+     */
-+    public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
-+        super();
-+        iMethodName = methodName;
-+        iParamTypes = paramTypes;
-+        iArgs = args;
-+    }
-+
-+    /**
-+     * Transforms the input to result by invoking a method on the input.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result, null if null input
-+     */
-+    public Object transform(Object input) {
-+        if (input == null) {
-+            return null;
-+        }
-+        try {
-+            Class cls = input.getClass();
-+            Method method = cls.getMethod(iMethodName, iParamTypes);
-+            return method.invoke(input, iArgs);
-+
-+        } catch (NoSuchMethodException ex) {
-+            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist");
-+        } catch (IllegalAccessException ex) {
-+            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
-+        } catch (InvocationTargetException ex) {
-+            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/MapTransformer.java
-@@ -0,0 +1,90 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+import java.util.Map;
-+
-+/**
-+ * Transformer implementation that returns the value held in a specified map
-+ * using the input parameter as a key.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class MapTransformer <I,O> implements Transformer<I, O>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 862391807045468939L;
-+
-+    /**
-+     * The map of data to lookup in
-+     */
-+    private final Map<I, O> iMap;
-+
-+    /**
-+     * Factory to create the transformer.
-+     * <p/>
-+     * If the map is null, a transformer that always returns null is returned.
-+     *
-+     * @param map the map, not cloned
-+     * @return the transformer
-+     */
-+    public static <I,O> Transformer<I, O> getInstance(Map<I, O> map) {
-+        if (map == null) {
-+            return ConstantTransformer.NULL_INSTANCE;
-+        }
-+        return new MapTransformer<I, O>(map);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param map the map to use for lookup, not cloned
-+     */
-+    private MapTransformer(Map<I, O> map) {
-+        super();
-+        iMap = map;
-+    }
-+
-+    /**
-+     * Transforms the input to result by looking it up in a <code>Map</code>.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public O transform(I input) {
-+        return iMap.get(input);
-+    }
-+
-+    /**
-+     * Gets the map to lookup in.
-+     *
-+     * @return the map
-+     * @since Commons Collections 3.1
-+     */
-+    public Map<I, O> getMap() {
-+        return iMap;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NOPClosure.java
-@@ -0,0 +1,68 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Closure implementation that does nothing.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class NOPClosure <T> implements Closure<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 3518477308466486130L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Closure INSTANCE = new NOPClosure();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+	public static <T> Closure<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Constructor
-+     */
-+    private NOPClosure() {
-+        super();
-+    }
-+
-+    /**
-+     * Do nothing.
-+     *
-+     * @param input the input object
-+     */
-+    public void execute(T input) {
-+        // do nothing
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NOPTransformer.java
-@@ -0,0 +1,69 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that does nothing.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class NOPTransformer <I> implements Transformer<I, I>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 2133891748318574490L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Transformer INSTANCE = new NOPTransformer();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+	public static <T> Transformer<T,T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Constructor
-+     */
-+    private NOPTransformer() {
-+        super();
-+    }
-+
-+    /**
-+     * Transforms the input to result by doing nothing.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result which is the input
-+     */
-+    public I transform(I input) {
-+        return input;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NonePredicate.java
-@@ -0,0 +1,108 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+
-+/**
-+ * Predicate implementation that returns true if none of the predicates return true.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class NonePredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 2007613066565892961L;
-+
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T>[] iPredicates;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>any</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<? super T>[] predicates) {
-+        FunctorUtils.validateMin2(predicates);
-+        predicates = FunctorUtils.copy(predicates);
-+        return new NonePredicate<T>(predicates);
-+    }
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>one</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     */
-+    public static <T> Predicate<T> getInstance(Collection<Predicate<? super T>> predicates) {
-+        Predicate[] preds = FunctorUtils.validate(predicates);
-+        return new NonePredicate<T>(preds);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicates the predicates to check, not cloned, not null
-+     */
-+    public NonePredicate(Predicate[] predicates) {
-+        super();
-+        iPredicates = predicates;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning false if any stored predicate returns false.
-+     *
-+     * @param object the input object
-+     * @return true if none of decorated predicates return true
-+     */
-+    public boolean evaluate(T object) {
-+        for (int i = 0; i < iPredicates.length; i++) {
-+            if (iPredicates[i].evaluate(object)) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Gets the predicates, do not modify the array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return iPredicates;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NotNullPredicate.java
-@@ -0,0 +1,69 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if the input is not null.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class NotNullPredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7533784454832764388L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Predicate INSTANCE = new NotNullPredicate();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+    public static <T> Predicate<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private NotNullPredicate() {
-+        super();
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if the object does not equal null.
-+     *
-+     * @param object the object to evaluate
-+     * @return true if not null
-+     */
-+    public boolean evaluate(T object) {
-+        return (object != null);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NotPredicate.java
-@@ -0,0 +1,87 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns the opposite of the decorated predicate.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class NotPredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -2654603322338049674L;
-+
-+    /**
-+     * The predicate to decorate
-+     */
-+    private final Predicate<T> iPredicate;
-+
-+    /**
-+     * Factory to create the not predicate.
-+     *
-+     * @param predicate the predicate to decorate, not null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<T> predicate) {
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        return new NotPredicate<T>(predicate);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate the predicate to call after the null check
-+     */
-+    public NotPredicate(Predicate<T> predicate) {
-+        super();
-+        iPredicate = predicate;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning the opposite to the stored predicate.
-+     *
-+     * @param object the input object
-+     * @return true if predicate returns false
-+     */
-+    public boolean evaluate(T object) {
-+        return !(iPredicate.evaluate(object));
-+    }
-+
-+    /**
-+     * Gets the predicate being decorated.
-+     *
-+     * @return the predicate as the only element in an array
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return new Predicate[]{iPredicate};
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NullIsExceptionPredicate.java
-@@ -0,0 +1,93 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.FunctorException;
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that throws an exception if the input is null.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class NullIsExceptionPredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 3243449850504576071L;
-+
-+    /**
-+     * The predicate to decorate
-+     */
-+    private final Predicate<T> iPredicate;
-+
-+    /**
-+     * Factory to create the null exception predicate.
-+     *
-+     * @param predicate the predicate to decorate, not null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<T> predicate) {
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        return new NullIsExceptionPredicate<T>(predicate);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate the predicate to call after the null check
-+     */
-+    public NullIsExceptionPredicate(Predicate<T> predicate) {
-+        super();
-+        iPredicate = predicate;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning the result of the decorated predicate
-+     * once a null check is performed.
-+     *
-+     * @param object the input object
-+     * @return true if decorated predicate returns true
-+     * @throws FunctorException if input is null
-+     */
-+    public boolean evaluate(T object) {
-+        if (object == null) {
-+            throw new FunctorException("Input Object must not be null");
-+        }
-+        return iPredicate.evaluate(object);
-+    }
-+
-+    /**
-+     * Gets the predicate being decorated.
-+     *
-+     * @return the predicate as the only element in an array
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return new Predicate[]{iPredicate};
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NullIsFalsePredicate.java
-@@ -0,0 +1,91 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns false if the input is null.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class NullIsFalsePredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -2997501534564735525L;
-+
-+    /**
-+     * The predicate to decorate
-+     */
-+    private final Predicate<T> iPredicate;
-+
-+    /**
-+     * Factory to create the null false predicate.
-+     *
-+     * @param predicate the predicate to decorate, not null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<T> predicate) {
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        return new NullIsFalsePredicate<T>(predicate);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate the predicate to call after the null check
-+     */
-+    public NullIsFalsePredicate(Predicate<T> predicate) {
-+        super();
-+        iPredicate = predicate;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning the result of the decorated predicate
-+     * once a null check is performed.
-+     *
-+     * @param object the input object
-+     * @return true if decorated predicate returns true, false if input is null
-+     */
-+    public boolean evaluate(T object) {
-+        if (object == null) {
-+            return false;
-+        }
-+        return iPredicate.evaluate(object);
-+    }
-+
-+    /**
-+     * Gets the predicate being decorated.
-+     *
-+     * @return the predicate as the only element in an array
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return new Predicate[]{iPredicate};
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NullIsTruePredicate.java
-@@ -0,0 +1,91 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if the input is null.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class NullIsTruePredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -7625133768987126273L;
-+
-+    /**
-+     * The predicate to decorate
-+     */
-+    private final Predicate<T> iPredicate;
-+
-+    /**
-+     * Factory to create the null true predicate.
-+     *
-+     * @param predicate the predicate to decorate, not null
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<T> predicate) {
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        return new NullIsTruePredicate<T>(predicate);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate the predicate to call after the null check
-+     */
-+    public NullIsTruePredicate(Predicate<T> predicate) {
-+        super();
-+        iPredicate = predicate;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning the result of the decorated predicate
-+     * once a null check is performed.
-+     *
-+     * @param object the input object
-+     * @return true if decorated predicate returns true or input is null
-+     */
-+    public boolean evaluate(T object) {
-+        if (object == null) {
-+            return true;
-+        }
-+        return iPredicate.evaluate(object);
-+    }
-+
-+    /**
-+     * Gets the predicate being decorated.
-+     *
-+     * @return the predicate as the only element in an array
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return new Predicate[]{iPredicate};
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/NullPredicate.java
-@@ -0,0 +1,69 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if the input is null.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class NullPredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7533784454832764388L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Predicate INSTANCE = new NullPredicate();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+    public static <T> Predicate<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private NullPredicate() {
-+        super();
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if the input is null.
-+     *
-+     * @param object the input object
-+     * @return true if input is null
-+     */
-+    public boolean evaluate(T object) {
-+        return (object == null);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/OnePredicate.java
-@@ -0,0 +1,113 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+
-+/**
-+ * Predicate implementation that returns true if only one of the predicates return true.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class OnePredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -8125389089924745785L;
-+
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T>[] iPredicates;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>any</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<? super T>[] predicates) {
-+        FunctorUtils.validateMin2(predicates);
-+        predicates = FunctorUtils.copy(predicates);
-+        return new OnePredicate<T>(predicates);
-+    }
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicates the predicates to check, cloned, not null
-+     * @return the <code>one</code> predicate
-+     * @throws IllegalArgumentException if the predicates array is null
-+     * @throws IllegalArgumentException if any predicate in the array is null
-+     * @throws IllegalArgumentException if the predicates array has less than 2 elements
-+     */
-+    public static <T> Predicate<T> getInstance(Collection<Predicate<? super T>> predicates) {
-+        Predicate[] preds = FunctorUtils.validate(predicates);
-+        return new OnePredicate<T>(preds);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicates the predicates to check, not cloned, not null
-+     */
-+    public OnePredicate(Predicate<? super T>[] predicates) {
-+        super();
-+        iPredicates = predicates;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if only one decorated predicate
-+     * returns true.
-+     *
-+     * @param object the input object
-+     * @return true if only one decorated predicate returns true
-+     */
-+    public boolean evaluate(T object) {
-+        boolean match = false;
-+        for (int i = 0; i < iPredicates.length; i++) {
-+            if (iPredicates[i].evaluate(object)) {
-+                if (match) {
-+                    return false;
-+                }
-+                match = true;
-+            }
-+        }
-+        return match;
-+    }
-+
-+    /**
-+     * Gets the predicates, do not modify the array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return iPredicates;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/OrPredicate.java
-@@ -0,0 +1,94 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns true if either of the predicates return true.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class OrPredicate <T> implements Predicate<T>, PredicateDecorator<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -8791518325735182855L;
-+
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T> iPredicate1;
-+    /**
-+     * The array of predicates to call
-+     */
-+    private final Predicate<? super T> iPredicate2;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param predicate1 the first predicate to check, not null
-+     * @param predicate2 the second predicate to check, not null
-+     * @return the <code>and</code> predicate
-+     * @throws IllegalArgumentException if either predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        if (predicate1 == null || predicate2 == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        return new OrPredicate<T>(predicate1, predicate2);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate1 the first predicate to check, not null
-+     * @param predicate2 the second predicate to check, not null
-+     */
-+    public OrPredicate(Predicate<? super T> predicate1, Predicate<? super T> predicate2) {
-+        super();
-+        iPredicate1 = predicate1;
-+        iPredicate2 = predicate2;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if either predicate returns true.
-+     *
-+     * @param object the input object
-+     * @return true if either decorated predicate returns true
-+     */
-+    public boolean evaluate(T object) {
-+        return (iPredicate1.evaluate(object) || iPredicate2.evaluate(object));
-+    }
-+
-+    /**
-+     * Gets the two predicates being decorated as an array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return new Predicate[]{iPredicate1, iPredicate2};
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/PredicateDecorator.java
-@@ -0,0 +1,42 @@
-+// GenericsNote: Converted (no generics required).
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+/**
-+ * Defines a predicate that decorates one or more other predicates.
-+ * <p/>
-+ * This interface enables tools to access the decorated predicates.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.1
-+ */
-+public interface PredicateDecorator <T> extends Predicate<T> {
-+
-+    /**
-+     * Gets the predicates being decorated as an array.
-+     * <p/>
-+     * The array may be the internal data structure of the predicate and thus
-+     * should not be altered.
-+     *
-+     * @return the predicates being decorated
-+     */
-+    Predicate<? super T>[] getPredicates();
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/PredicateTransformer.java
-@@ -0,0 +1,89 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that calls a Predicate using the input object
-+ * and then returns the input.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicateTransformer <T> implements Transformer<T, Boolean>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 5278818408044349346L;
-+
-+    /**
-+     * The closure to wrap
-+     */
-+    private final Predicate<T> iPredicate;
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param predicate the predicate to call, not null
-+     * @return the <code>predicate</code> transformer
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Transformer<T, Boolean> getInstance(Predicate<T> predicate) {
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        return new PredicateTransformer<T>(predicate);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate the predicate to call, not null
-+     */
-+    public PredicateTransformer(Predicate<T> predicate) {
-+        super();
-+        iPredicate = predicate;
-+    }
-+
-+    /**
-+     * Transforms the input to result by calling a predicate.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public Boolean transform(T input) {
-+        return (iPredicate.evaluate(input) ? Boolean.TRUE : Boolean.FALSE);
-+    }
-+
-+    /**
-+     * Gets the predicate.
-+     *
-+     * @return the predicate
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<T> getPredicate() {
-+        return iPredicate;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/PrototypeFactory.java
-@@ -0,0 +1,210 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Factory;
-+import org.apache.commons.collections15.FunctorException;
-+
-+import java.io.*;
-+import java.lang.reflect.InvocationTargetException;
-+import java.lang.reflect.Method;
-+
-+/**
-+ * Factory implementation that creates a new instance each time based on a prototype.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PrototypeFactory <T> {
-+
-+    /**
-+     * Factory method that performs validation.
-+     * <p/>
-+     * Creates a Factory that will return a clone of the same prototype object
-+     * each time the factory is used. The prototype will be cloned using one of these
-+     * techniques (in order):
-+     * <ul>
-+     * <li>public clone method
-+     * <li>public copy constructor
-+     * <li>serialization clone
-+     * <ul>
-+     *
-+     * @param prototype the object to clone each time in the factory
-+     * @return the <code>prototype</code> factory
-+     * @throws IllegalArgumentException if the prototype is null
-+     * @throws IllegalArgumentException if the prototype cannot be cloned
-+     */
-+    public static <T> Factory<T> getInstance(T prototype) {
-+        if (prototype == null) {
-+            return ConstantFactory.NULL_INSTANCE;
-+        }
-+        try {
-+            Method method = prototype.getClass().getMethod("clone", null);
-+            return new PrototypeCloneFactory<T>(prototype, method);
-+
-+        } catch (NoSuchMethodException ex) {
-+            try {
-+                prototype.getClass().getConstructor(new Class[]{prototype.getClass()});
-+                return new InstantiateFactory<T>((Class<T>) prototype.getClass(), new Class[]{prototype.getClass()}, new Object[]{prototype});
-+
-+            } catch (NoSuchMethodException ex2) {
-+                if (prototype instanceof Serializable) {
-+                    return new PrototypeSerializationFactory((Serializable) prototype);
-+                }
-+            }
-+        }
-+        throw new IllegalArgumentException("The prototype must be cloneable via a public clone method");
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     */
-+    private PrototypeFactory() {
-+        super();
-+    }
-+
-+    // PrototypeCloneFactory
-+    //-----------------------------------------------------------------------
-+    /**
-+     * PrototypeCloneFactory creates objects by copying a prototype using the clone method.
-+     */
-+    static class PrototypeCloneFactory <T> implements Factory<T>, Serializable {
-+
-+        /**
-+         * The serial version
-+         */
-+        static final long serialVersionUID = 5604271422565175555L;
-+
-+        /**
-+         * The object to clone each time
-+         */
-+        private final T iPrototype;
-+        /**
-+         * The method used to clone
-+         */
-+        private transient Method iCloneMethod;
-+
-+        /**
-+         * Constructor to store prototype.
-+         */
-+        private PrototypeCloneFactory(T prototype, Method method) {
-+            super();
-+            iPrototype = prototype;
-+            iCloneMethod = method;
-+        }
-+
-+        /**
-+         * Find the Clone method for the class specified.
-+         */
-+        private void findCloneMethod() {
-+            try {
-+                iCloneMethod = iPrototype.getClass().getMethod("clone", null);
-+
-+            } catch (NoSuchMethodException ex) {
-+                throw new IllegalArgumentException("PrototypeCloneFactory: The clone method must exist and be public ");
-+            }
-+        }
-+
-+        /**
-+         * Creates an object by calling the clone method.
-+         *
-+         * @return the new object
-+         */
-+        public T create() {
-+            // needed for post-serialization
-+            if (iCloneMethod == null) {
-+                findCloneMethod();
-+            }
-+
-+            try {
-+                return (T) iCloneMethod.invoke(iPrototype, null);
-+
-+            } catch (IllegalAccessException ex) {
-+                throw new FunctorException("PrototypeCloneFactory: Clone method must be public", ex);
-+            } catch (InvocationTargetException ex) {
-+                throw new FunctorException("PrototypeCloneFactory: Clone method threw an exception", ex);
-+            }
-+        }
-+    }
-+
-+    // PrototypeSerializationFactory
-+    //-----------------------------------------------------------------------
-+    /**
-+     * PrototypeSerializationFactory creates objects by cloning a prototype using serialization.
-+     */
-+    static class PrototypeSerializationFactory <T extends Serializable> implements Factory<T>, Serializable {
-+
-+        /**
-+         * The serial version
-+         */
-+        static final long serialVersionUID = -8704966966139178833L;
-+
-+        /**
-+         * The object to clone via serialization each time
-+         */
-+        private final Serializable iPrototype;
-+
-+        /**
-+         * Constructor to store prototype
-+         */
-+        private PrototypeSerializationFactory(Serializable prototype) {
-+            super();
-+            iPrototype = prototype;
-+        }
-+
-+        /**
-+         * Creates an object using serialization.
-+         *
-+         * @return the new object
-+         */
-+        public T create() {
-+            ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
-+            ByteArrayInputStream bais = null;
-+            try {
-+                ObjectOutputStream out = new ObjectOutputStream(baos);
-+                out.writeObject(iPrototype);
-+
-+                bais = new ByteArrayInputStream(baos.toByteArray());
-+                ObjectInputStream in = new ObjectInputStream(bais);
-+                return (T) in.readObject();
-+
-+            } catch (ClassNotFoundException ex) {
-+                throw new FunctorException(ex);
-+            } catch (IOException ex) {
-+                throw new FunctorException(ex);
-+            } finally {
-+                try {
-+                    if (bais != null) {
-+                        bais.close();
-+                    }
-+                } catch (IOException ex) {
-+                    // ignore
-+                }
-+                try {
-+                    if (baos != null) {
-+                        baos.close();
-+                    }
-+                } catch (IOException ex) {
-+                    // ignore
-+                }
-+            }
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/StringValueTransformer.java
-@@ -0,0 +1,64 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Transformer implementation that returns the <code>String.valueOf</code>.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class StringValueTransformer <T> implements Transformer<T, String>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 7511110693171758606L;
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+    public static <T> Transformer<T, String> getInstance() {
-+        return new StringValueTransformer<T>();
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private StringValueTransformer() {
-+        super();
-+    }
-+
-+    /**
-+     * Transforms the input to result by calling <code>String.valueOf</code>.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public String transform(T input) {
-+        return String.valueOf(input);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/SwitchClosure.java
-@@ -0,0 +1,182 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+import java.util.Iterator;
-+import java.util.Map;
-+
-+/**
-+ * Closure implementation calls the closure whose predicate returns true,
-+ * like a switch statement.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SwitchClosure <T> implements Closure<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 3518477308466486130L;
-+
-+    /**
-+     * The tests to consider
-+     */
-+    private final Predicate<? super T>[] iPredicates;
-+    /**
-+     * The matching closures to call
-+     */
-+    private final Closure<? super T>[] iClosures;
-+    /**
-+     * The default closure to call if no tests match
-+     */
-+    private final Closure<? super T> iDefault;
-+
-+    /**
-+     * Factory method that performs validation and copies the parameter arrays.
-+     *
-+     * @param predicates     array of predicates, cloned, no nulls
-+     * @param closures       matching array of closures, cloned, no nulls
-+     * @param defaultClosure the closure to use if no match, null means nop
-+     * @return the <code>chained</code> closure
-+     * @throws IllegalArgumentException if array is null
-+     * @throws IllegalArgumentException if any element in the array is null
-+     */
-+    public static <T> Closure<T> getInstance(Predicate<? super T>[] predicates, Closure<? super T>[] closures, Closure<? super T> defaultClosure) {
-+        FunctorUtils.validate(predicates);
-+        FunctorUtils.validate(closures);
-+        if (predicates.length != closures.length) {
-+            throw new IllegalArgumentException("The predicate and closure arrays must be the same size");
-+        }
-+        if (predicates.length == 0) {
-+            return (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
-+        }
-+        predicates = FunctorUtils.copy(predicates);
-+        closures = FunctorUtils.copy(closures);
-+        return new SwitchClosure<T>(predicates, closures, defaultClosure);
-+    }
-+
-+    /**
-+     * Create a new Closure that calls one of the closures depending
-+     * on the predicates.
-+     * <p/>
-+     * The Map consists of Predicate keys and Closure values. A closure
-+     * is called if its matching predicate returns true. Each predicate is evaluated
-+     * until one returns true. If no predicates evaluate to true, the default
-+     * closure is called. The default closure is set in the map with a
-+     * null key. The ordering is that of the iterator() method on the entryset
-+     * collection of the map.
-+     *
-+     * @param predicatesAndClosures a map of predicates to closures
-+     * @return the <code>switch</code> closure
-+     * @throws IllegalArgumentException if the map is null
-+     * @throws IllegalArgumentException if any closure in the map is null
-+     * @throws ClassCastException       if the map elements are of the wrong type
-+     */
-+    public static <T> Closure<T> getInstance(Map<Predicate<? super T>, Closure<? super T>> predicatesAndClosures) {
-+        Closure[] closures = null;
-+        Predicate[] preds = null;
-+        if (predicatesAndClosures == null) {
-+            throw new IllegalArgumentException("The predicate and closure map must not be null");
-+        }
-+        if (predicatesAndClosures.size() == 0) {
-+            return NOPClosure.INSTANCE;
-+        }
-+        // convert to array like this to guarantee iterator() ordering
-+        Closure defaultClosure = (Closure) predicatesAndClosures.remove(null);
-+        int size = predicatesAndClosures.size();
-+        if (size == 0) {
-+            return (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
-+        }
-+        closures = new Closure[size];
-+        preds = new Predicate[size];
-+        int i = 0;
-+        for (Iterator it = predicatesAndClosures.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            preds[i] = (Predicate<? super T>) entry.getKey();
-+            closures[i] = (Closure<? super T>) entry.getValue();
-+            i++;
-+        }
-+        return new SwitchClosure<T>(preds, closures, defaultClosure);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicates     array of predicates, not cloned, no nulls
-+     * @param closures       matching array of closures, not cloned, no nulls
-+     * @param defaultClosure the closure to use if no match, null means nop
-+     */
-+    public SwitchClosure(Predicate<? super T>[] predicates, Closure<? super T>[] closures, Closure<? super T> defaultClosure) {
-+        super();
-+        iPredicates = predicates;
-+        iClosures = closures;
-+        iDefault = (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
-+    }
-+
-+    /**
-+     * Executes the closure whose matching predicate returns true
-+     *
-+     * @param input the input object
-+     */
-+    public void execute(T input) {
-+        for (int i = 0; i < iPredicates.length; i++) {
-+            if (iPredicates[i].evaluate(input) == true) {
-+                iClosures[i].execute(input);
-+                return;
-+            }
-+        }
-+        iDefault.execute(input);
-+    }
-+
-+    /**
-+     * Gets the predicates, do not modify the array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T>[] getPredicates() {
-+        return iPredicates;
-+    }
-+
-+    /**
-+     * Gets the closures, do not modify the array.
-+     *
-+     * @return the closures
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<? super T>[] getClosures() {
-+        return iClosures;
-+    }
-+
-+    /**
-+     * Gets the default closure.
-+     *
-+     * @return the default closure
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<? super T> getDefaultClosure() {
-+        return iDefault;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/SwitchTransformer.java
-@@ -0,0 +1,183 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+import java.util.Iterator;
-+import java.util.Map;
-+
-+/**
-+ * Transformer implementation calls the transformer whose predicate returns true,
-+ * like a switch statement.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SwitchTransformer <I,O> implements Transformer<I, O>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -6404460890903469332L;
-+
-+    /**
-+     * The tests to consider
-+     */
-+    private final Predicate<? super I>[] iPredicates;
-+    /**
-+     * The matching transformers to call
-+     */
-+    private final Transformer<? super I, ? extends O>[] iTransformers;
-+    /**
-+     * The default transformer to call if no tests match
-+     */
-+    private final Transformer<? super I, ? extends O> iDefault;
-+
-+    /**
-+     * Factory method that performs validation and copies the parameter arrays.
-+     *
-+     * @param predicates         array of predicates, cloned, no nulls
-+     * @param transformers       matching array of transformers, cloned, no nulls
-+     * @param defaultTransformer the transformer to use if no match, null means nop
-+     * @return the <code>chained</code> transformer
-+     * @throws IllegalArgumentException if array is null
-+     * @throws IllegalArgumentException if any element in the array is null
-+     */
-+    public static <I,O> Transformer<I, O> getInstance(Predicate<? super I>[] predicates, Transformer<? super I, ? extends O>[] transformers, Transformer<? super I, ? extends O> defaultTransformer) {
-+        FunctorUtils.validate(predicates);
-+        FunctorUtils.validate(transformers);
-+        if (predicates.length != transformers.length) {
-+            throw new IllegalArgumentException("The predicate and transformer arrays must be the same size");
-+        }
-+        if (predicates.length == 0) {
-+            return (defaultTransformer == null ? ConstantTransformer.NULL_INSTANCE : defaultTransformer);
-+        }
-+        predicates = FunctorUtils.copy(predicates);
-+        transformers = FunctorUtils.copy(transformers);
-+        return new SwitchTransformer<I, O>(predicates, transformers, defaultTransformer);
-+    }
-+
-+    /**
-+     * Create a new Transformer that calls one of the transformers depending
-+     * on the predicates.
-+     * <p/>
-+     * The Map consists of Predicate keys and Transformer values. A transformer
-+     * is called if its matching predicate returns true. Each predicate is evaluated
-+     * until one returns true. If no predicates evaluate to true, the default
-+     * transformer is called. The default transformer is set in the map with a
-+     * null key. The ordering is that of the iterator() method on the entryset
-+     * collection of the map.
-+     *
-+     * @param predicatesAndTransformers a map of predicates to transformers
-+     * @return the <code>switch</code> transformer
-+     * @throws IllegalArgumentException if the map is null
-+     * @throws IllegalArgumentException if any transformer in the map is null
-+     * @throws ClassCastException       if the map elements are of the wrong type
-+     */
-+    public static <I,O> Transformer<I, O> getInstance(Map<Predicate<? super I>, Transformer<? super I, ? extends O>> predicatesAndTransformers) {
-+        Transformer<? super I, ? extends O>[] transformers = null;
-+        Predicate<? super I>[] preds = null;
-+        if (predicatesAndTransformers == null) {
-+            throw new IllegalArgumentException("The predicate and transformer map must not be null");
-+        }
-+        if (predicatesAndTransformers.size() == 0) {
-+            return ConstantTransformer.NULL_INSTANCE;
-+        }
-+        // convert to array like this to guarantee iterator() ordering
-+        Transformer<? super I, ? extends O> defaultTransformer = predicatesAndTransformers.remove(null);
-+        int size = predicatesAndTransformers.size();
-+        if (size == 0) {
-+            return (defaultTransformer == null ? ConstantTransformer.NULL_INSTANCE : defaultTransformer);
-+        }
-+        transformers = new Transformer[size];
-+        preds = new Predicate[size];
-+        int i = 0;
-+        for (Iterator<Map.Entry<Predicate<? super I>, Transformer<? super I, ? extends O>>> it = predicatesAndTransformers.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<Predicate<? super I>, Transformer<? super I, ? extends O>> entry = it.next();
-+            preds[i] = entry.getKey();
-+            transformers[i] = entry.getValue();
-+            i++;
-+        }
-+        return new SwitchTransformer<I, O>(preds, transformers, defaultTransformer);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicates         array of predicates, not cloned, no nulls
-+     * @param transformers       matching array of transformers, not cloned, no nulls
-+     * @param defaultTransformer the transformer to use if no match, null means nop
-+     */
-+    public SwitchTransformer(Predicate<? super I>[] predicates, Transformer<? super I, ? extends O>[] transformers, Transformer<? super I, ? extends O> defaultTransformer) {
-+        super();
-+        iPredicates = predicates;
-+        iTransformers = transformers;
-+        iDefault = (defaultTransformer == null ? ConstantTransformer.NULL_INSTANCE : defaultTransformer);
-+    }
-+
-+    /**
-+     * Transforms the input to result by calling the transformer whose matching
-+     * predicate returns true.
-+     *
-+     * @param input the input object to transform
-+     * @return the transformed result
-+     */
-+    public O transform(I input) {
-+        for (int i = 0; i < iPredicates.length; i++) {
-+            if (iPredicates[i].evaluate(input) == true) {
-+                return iTransformers[i].transform(input);
-+            }
-+        }
-+        return (O) iDefault.transform(input);
-+    }
-+
-+    /**
-+     * Gets the predicates, do not modify the array.
-+     *
-+     * @return the predicates
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super I>[] getPredicates() {
-+        return iPredicates;
-+    }
-+
-+    /**
-+     * Gets the transformers, do not modify the array.
-+     *
-+     * @return the transformers
-+     * @since Commons Collections 3.1
-+     */
-+    public Transformer<? super I, ? extends O>[] getTransformers() {
-+        return iTransformers;
-+    }
-+
-+    /**
-+     * Gets the default transformer.
-+     *
-+     * @return the default transformer
-+     * @since Commons Collections 3.1
-+     */
-+    public Transformer<? super I, ? extends O> getDefaultTransformer() {
-+        return iDefault;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/TransformedPredicate.java
-@@ -0,0 +1,115 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that transforms the given object before invoking
-+ * another <code>Predicate</code>.
-+ * <p>
-+ * Note: This class cannot suppport generics without breaking the {@link PredicateDecorator} interface.
-+ *
-+ * @author Matt Hall, John Watkinson, Alban Peignier
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.1
-+ */
-+public final class TransformedPredicate <I,O> implements Predicate<I>, PredicateDecorator<I>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -5596090919668315834L;
-+
-+    /**
-+     * The transformer to call
-+     */
-+    private final Transformer<? super I, ? extends O> iTransformer;
-+    /**
-+     * The predicate to call
-+     */
-+    private final Predicate<? super O> iPredicate;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param transformer the transformer to call
-+     * @param predicate   the predicate to call with the result of the transform
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the transformer or the predicate is null
-+     */
-+    public static <I,O> Predicate<I> getInstance(Transformer<? super I, ? extends O> transformer, Predicate<? super O> predicate) {
-+        if (transformer == null) {
-+            throw new IllegalArgumentException("The transformer to call must not be null");
-+        }
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("The predicate to call must not be null");
-+        }
-+        return new TransformedPredicate<I, O>(transformer, predicate);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param transformer the transformer to use
-+     * @param predicate   the predicate to decorate
-+     */
-+    public TransformedPredicate(Transformer<? super I, ? extends O> transformer, Predicate<? super O> predicate) {
-+        iTransformer = transformer;
-+        iPredicate = predicate;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning the result of the decorated predicate
-+     * once the input has been transformed
-+     *
-+     * @param object the input object which will be transformed
-+     * @return true if decorated predicate returns true
-+     */
-+    public boolean evaluate(I object) {
-+        O result = iTransformer.transform(object);
-+        return iPredicate.evaluate(result);
-+    }
-+
-+    /**
-+     * Gets the predicate being decorated.
-+     * <p/>
-+     * Not type-safe in 1.5.
-+     * <p/>
-+     *
-+     * @return the predicate as the only element in an array
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate[] getPredicates() {
-+        return new Predicate[]{iPredicate};
-+    }
-+
-+    /**
-+     * Gets the transformer in use.
-+     *
-+     * @return the transformer
-+     */
-+    public Transformer<? super I, ? extends O> getTransformer() {
-+        return iTransformer;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/TransformerClosure.java
-@@ -0,0 +1,89 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Closure implementation that calls a Transformer using the input object
-+ * and ignore the result.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformerClosure <I,O> implements Closure<I>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -5194992589193388969L;
-+
-+    /**
-+     * The transformer to wrap
-+     */
-+    private final Transformer<? super I, O> iTransformer;
-+
-+    /**
-+     * Factory method that performs validation.
-+     * <p/>
-+     * A null transformer will return the <code>NOPClosure</code>.
-+     *
-+     * @param transformer the transformer to call, null means nop
-+     * @return the <code>transformer</code> closure
-+     */
-+    public static <I,O> Closure<I> getInstance(Transformer<? super I, O> transformer) {
-+        if (transformer == null) {
-+            return NOPClosure.INSTANCE;
-+        }
-+        return new TransformerClosure<I, O>(transformer);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param transformer the transformer to call, not null
-+     */
-+    public TransformerClosure(Transformer<? super I, O> transformer) {
-+        super();
-+        iTransformer = transformer;
-+    }
-+
-+    /**
-+     * Executes the closure by calling the decorated transformer.
-+     *
-+     * @param input the input object
-+     */
-+    public void execute(I input) {
-+        iTransformer.transform(input);
-+    }
-+
-+    /**
-+     * Gets the transformer.
-+     *
-+     * @return the transformer
-+     * @since Commons Collections 3.1
-+     */
-+    public Transformer<? super I, O> getTransformer() {
-+        return iTransformer;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/TransformerPredicate.java
-@@ -0,0 +1,94 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.FunctorException;
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that returns the result of a transformer.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class TransformerPredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -2407966402920578741L;
-+
-+    /**
-+     * The transformer to call
-+     */
-+    private final Transformer<T, Boolean> iTransformer;
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @param transformer the transformer to decorate
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the transformer is null
-+     */
-+    public static <T> Predicate<T> getInstance(Transformer<T, Boolean> transformer) {
-+        if (transformer == null) {
-+            throw new IllegalArgumentException("The transformer to call must not be null");
-+        }
-+        return new TransformerPredicate<T>(transformer);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param transformer the transformer to decorate
-+     */
-+    public TransformerPredicate(Transformer<T, Boolean> transformer) {
-+        super();
-+        iTransformer = transformer;
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning the result of the decorated transformer.
-+     *
-+     * @param object the input object
-+     * @return true if decorated transformer returns Boolean.TRUE
-+     * @throws FunctorException if the transformer returns an invalid type
-+     */
-+    public boolean evaluate(T object) {
-+        Boolean result = iTransformer.transform(object);
-+        if (result == null) {
-+            throw new FunctorException("Transformer must return an instanceof Boolean, it was a " + (result == null ? "null object" : result.getClass().getName()));
-+        }
-+        return result.booleanValue();
-+    }
-+
-+    /**
-+     * Gets the transformer.
-+     *
-+     * @return the transformer
-+     * @since Commons Collections 3.1
-+     */
-+    public Transformer<T, Boolean> getTransformer() {
-+        return iTransformer;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/TruePredicate.java
-@@ -0,0 +1,69 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Predicate implementation that always returns true.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class TruePredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = 3374767158756189740L;
-+
-+    /**
-+     * Singleton predicate instance
-+     */
-+    public static final Predicate INSTANCE = new TruePredicate();
-+
-+    /**
-+     * Factory returning the singleton instance.
-+     *
-+     * @return the singleton instance
-+     * @since Commons Collections 3.1
-+     */
-+    public static <T> Predicate<T> getInstance() {
-+        return INSTANCE;
-+    }
-+
-+    /**
-+     * Restricted constructor.
-+     */
-+    private TruePredicate() {
-+        super();
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true always.
-+     *
-+     * @param object the input object
-+     * @return true always
-+     */
-+    public boolean evaluate(T object) {
-+        return true;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/UniquePredicate.java
-@@ -0,0 +1,74 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+import java.util.HashSet;
-+import java.util.Set;
-+
-+/**
-+ * Predicate implementation that returns true the first time an object is
-+ * passed into the predicate.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UniquePredicate <T> implements Predicate<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -3319417438027438040L;
-+
-+    /**
-+     * The set of previously seen objects
-+     */
-+    private final Set<T> iSet = new HashSet<T>();
-+
-+    /**
-+     * Factory to create the predicate.
-+     *
-+     * @return the predicate
-+     * @throws IllegalArgumentException if the predicate is null
-+     */
-+    public static <T> Predicate<T> getInstance() {
-+        return new UniquePredicate<T>();
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     */
-+    public UniquePredicate() {
-+        super();
-+    }
-+
-+    /**
-+     * Evaluates the predicate returning true if the input object hasn't been
-+     * received yet.
-+     *
-+     * @param object the input object
-+     * @return true if this is the first time the object is seen
-+     */
-+    public boolean evaluate(T object) {
-+        return iSet.add(object);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/WhileClosure.java
-@@ -0,0 +1,130 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.functors;
-+
-+import org.apache.commons.collections15.Closure;
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.Serializable;
-+
-+/**
-+ * Closure implementation that executes a closure repeatedly until a condition is met,
-+ * like a do-while or while loop.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class WhileClosure <T> implements Closure<T>, Serializable {
-+
-+    /**
-+     * Serial version UID
-+     */
-+    static final long serialVersionUID = -3110538116913760108L;
-+
-+    /**
-+     * The test condition
-+     */
-+    private final Predicate<? super T> iPredicate;
-+    /**
-+     * The closure to call
-+     */
-+    private final Closure<? super T> iClosure;
-+    /**
-+     * The flag, true is a do loop, false is a while
-+     */
-+    private final boolean iDoLoop;
-+
-+    /**
-+     * Factory method that performs validation.
-+     *
-+     * @param predicate the predicate used to evaluate when the loop terminates, not null
-+     * @param closure   the closure the execute, not null
-+     * @param doLoop    true to act as a do-while loop, always executing the closure once
-+     * @return the <code>while</code> closure
-+     * @throws IllegalArgumentException if the predicate or closure is null
-+     */
-+    public static <T> Closure<T> getInstance(Predicate<? super T> predicate, Closure<? super T> closure, boolean doLoop) {
-+        if (predicate == null) {
-+            throw new IllegalArgumentException("Predicate must not be null");
-+        }
-+        if (closure == null) {
-+            throw new IllegalArgumentException("Closure must not be null");
-+        }
-+        return new WhileClosure<T>(predicate, closure, doLoop);
-+    }
-+
-+    /**
-+     * Constructor that performs no validation.
-+     * Use <code>getInstance</code> if you want that.
-+     *
-+     * @param predicate the predicate used to evaluate when the loop terminates, not null
-+     * @param closure   the closure the execute, not null
-+     * @param doLoop    true to act as a do-while loop, always executing the closure once
-+     */
-+    public WhileClosure(Predicate<? super T> predicate, Closure<? super T> closure, boolean doLoop) {
-+        super();
-+        iPredicate = predicate;
-+        iClosure = closure;
-+        iDoLoop = doLoop;
-+    }
-+
-+    /**
-+     * Executes the closure until the predicate is false.
-+     *
-+     * @param input the input object
-+     */
-+    public void execute(T input) {
-+        if (iDoLoop) {
-+            iClosure.execute(input);
-+        }
-+        while (iPredicate.evaluate(input)) {
-+            iClosure.execute(input);
-+        }
-+    }
-+
-+    /**
-+     * Gets the predicate in use.
-+     *
-+     * @return the predicate
-+     * @since Commons Collections 3.1
-+     */
-+    public Predicate<? super T> getPredicate() {
-+        return iPredicate;
-+    }
-+
-+    /**
-+     * Gets the closure.
-+     *
-+     * @return the closure
-+     * @since Commons Collections 3.1
-+     */
-+    public Closure<? super T> getClosure() {
-+        return iClosure;
-+    }
-+
-+    /**
-+     * Is the loop a do-while loop.
-+     *
-+     * @return true is do-while, false if while
-+     * @since Commons Collections 3.1
-+     */
-+    public boolean isDoLoop() {
-+        return iDoLoop;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/functors/package.html
-@@ -0,0 +1,26 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:24 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link org.apache.commons.collections.Closure Closure},
-+{@link org.apache.commons.collections.Predicate Predicate},
-+{@link org.apache.commons.collections.Predicate Transformer} and
-+{@link org.apache.commons.collections.Predicate Factory} interfaces.
-+These provide simple callbacks for processing with collections.
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/AbstractEmptyIterator.java
-@@ -0,0 +1,89 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * Provides an implementation of an empty iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.1
-+ */
-+abstract class AbstractEmptyIterator <E> {
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected AbstractEmptyIterator() {
-+        super();
-+    }
-+
-+    public boolean hasNext() {
-+        return false;
-+    }
-+
-+    public E next() {
-+        throw new NoSuchElementException("Iterator contains no elements");
-+    }
-+
-+    public boolean hasPrevious() {
-+        return false;
-+    }
-+
-+    public E previous() {
-+        throw new NoSuchElementException("Iterator contains no elements");
-+    }
-+
-+    public int nextIndex() {
-+        return 0;
-+    }
-+
-+    public int previousIndex() {
-+        return -1;
-+    }
-+
-+    public void add(E obj) {
-+        throw new UnsupportedOperationException("add() not supported for empty Iterator");
-+    }
-+
-+    public void set(E obj) {
-+        throw new IllegalStateException("Iterator contains no elements");
-+    }
-+
-+    public void remove() {
-+        throw new IllegalStateException("Iterator contains no elements");
-+    }
-+
-+    public E getKey() {
-+        throw new IllegalStateException("Iterator contains no elements");
-+    }
-+
-+    public E getValue() {
-+        throw new IllegalStateException("Iterator contains no elements");
-+    }
-+
-+    public E setValue(E value) {
-+        throw new IllegalStateException("Iterator contains no elements");
-+    }
-+
-+    public void reset() {
-+        // do nothing
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/AbstractIteratorDecorator.java
-@@ -0,0 +1,75 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * Provides basic behaviour for decorating an iterator with extra functionality.
-+ * <p/>
-+ * All methods are forwarded to the decorated iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, James Strachan
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class AbstractIteratorDecorator <E> implements Iterator<E> {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    protected final Iterator<E> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that decorates the specified iterator.
-+     *
-+     * @param iterator the iterator to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractIteratorDecorator(Iterator<E> iterator) {
-+        super();
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("Iterator must not be null");
-+        }
-+        this.iterator = iterator;
-+    }
-+
-+    /**
-+     * Gets the iterator being decorated.
-+     *
-+     * @return the decorated iterator
-+     */
-+    protected Iterator<E> getIterator() {
-+        return iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public E next() {
-+        return iterator.next();
-+    }
-+
-+    public void remove() {
-+        iterator.remove();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/AbstractListIteratorDecorator.java
-@@ -0,0 +1,99 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import java.util.ListIterator;
-+
-+/**
-+ * Provides basic behaviour for decorating a list iterator with extra functionality.
-+ * <p/>
-+ * All methods are forwarded to the decorated list iterator.
-+ *
-+ * @author Rodney Waldhoff
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class AbstractListIteratorDecorator <E> implements ListIterator<E> {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    protected final ListIterator<E> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that decorates the specified iterator.
-+     *
-+     * @param iterator the iterator to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractListIteratorDecorator(ListIterator<E> iterator) {
-+        super();
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("ListIterator must not be null");
-+        }
-+        this.iterator = iterator;
-+    }
-+
-+    /**
-+     * Gets the iterator being decorated.
-+     *
-+     * @return the decorated iterator
-+     */
-+    protected ListIterator<E> getListIterator() {
-+        return iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public E next() {
-+        return iterator.next();
-+    }
-+
-+    public int nextIndex() {
-+        return iterator.nextIndex();
-+    }
-+
-+    public boolean hasPrevious() {
-+        return iterator.hasPrevious();
-+    }
-+
-+    public E previous() {
-+        return iterator.previous();
-+    }
-+
-+    public int previousIndex() {
-+        return iterator.previousIndex();
-+    }
-+
-+    public void remove() {
-+        iterator.remove();
-+    }
-+
-+    public void set(E obj) {
-+        iterator.set(obj);
-+    }
-+
-+    public void add(E obj) {
-+        iterator.add(obj);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/AbstractMapIteratorDecorator.java
-@@ -0,0 +1,86 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.MapIterator;
-+
-+/**
-+ * Provides basic behaviour for decorating a map iterator with extra functionality.
-+ * <p/>
-+ * All methods are forwarded to the decorated map iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class AbstractMapIteratorDecorator <K,V> implements MapIterator<K, V> {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    protected final MapIterator<K, V> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that decorates the specified iterator.
-+     *
-+     * @param iterator the iterator to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractMapIteratorDecorator(MapIterator<K, V> iterator) {
-+        super();
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("MapIterator must not be null");
-+        }
-+        this.iterator = iterator;
-+    }
-+
-+    /**
-+     * Gets the iterator being decorated.
-+     *
-+     * @return the decorated iterator
-+     */
-+    protected MapIterator<K, V> getMapIterator() {
-+        return iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public K next() {
-+        return iterator.next();
-+    }
-+
-+    public void remove() {
-+        iterator.remove();
-+    }
-+
-+    public K getKey() {
-+        return iterator.getKey();
-+    }
-+
-+    public V getValue() {
-+        return iterator.getValue();
-+    }
-+
-+    public V setValue(V obj) {
-+        return iterator.setValue(obj);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/AbstractOrderedMapIteratorDecorator.java
-@@ -0,0 +1,94 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.OrderedMapIterator;
-+
-+/**
-+ * Provides basic behaviour for decorating an ordered map iterator with extra functionality.
-+ * <p/>
-+ * All methods are forwarded to the decorated map iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class AbstractOrderedMapIteratorDecorator <K,V> implements OrderedMapIterator<K, V> {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    protected final OrderedMapIterator<K, V> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that decorates the specified iterator.
-+     *
-+     * @param iterator the iterator to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractOrderedMapIteratorDecorator(OrderedMapIterator<K, V> iterator) {
-+        super();
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("OrderedMapIterator must not be null");
-+        }
-+        this.iterator = iterator;
-+    }
-+
-+    /**
-+     * Gets the iterator being decorated.
-+     *
-+     * @return the decorated iterator
-+     */
-+    protected OrderedMapIterator<K, V> getOrderedMapIterator() {
-+        return iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public K next() {
-+        return iterator.next();
-+    }
-+
-+    public boolean hasPrevious() {
-+        return iterator.hasPrevious();
-+    }
-+
-+    public K previous() {
-+        return iterator.previous();
-+    }
-+
-+    public void remove() {
-+        iterator.remove();
-+    }
-+
-+    public K getKey() {
-+        return iterator.getKey();
-+    }
-+
-+    public V getValue() {
-+        return iterator.getValue();
-+    }
-+
-+    public V setValue(V obj) {
-+        return iterator.setValue(obj);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/ArrayIterator.java
-@@ -0,0 +1,224 @@
-+// GenericsNote: Converted, although unsatisfying because there does not seem to be a way to generify the primitive types.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+import java.lang.reflect.Array;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * Implements an {@link java.util.Iterator Iterator} over any array.
-+ * <p/>
-+ * The array can be either an array of object or of primitives. If you know
-+ * that you have an object array, the
-+ * {@link org.apache.commons.collections15.iterators.ObjectArrayIterator ObjectArrayIterator}
-+ * class is a better choice, as it will perform better.
-+ * <p/>
-+ * The iterator implements a {@link #reset} method, allowing the reset of
-+ * the iterator back to the start if required.
-+ *
-+ * @author James Strachan
-+ * @author Mauricio S. Moura
-+ * @author Michael A. Smith
-+ * @author Neil O'Toole
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 1.0
-+ */
-+public class ArrayIterator <E> implements ResettableIterator<E> {
-+
-+    /**
-+     * The array to iterate over
-+     */
-+    protected Object array;
-+    /**
-+     * The start index to loop from
-+     */
-+    protected int startIndex = 0;
-+    /**
-+     * The end index to loop to
-+     */
-+    protected int endIndex = 0;
-+    /**
-+     * The current iterator index
-+     */
-+    protected int index = 0;
-+    
-+    // Constructors
-+    // ----------------------------------------------------------------------
-+    /**
-+     * Constructor for use with <code>setArray</code>.
-+     * <p/>
-+     * Using this constructor, the iterator is equivalent to an empty iterator
-+     * until {@link #setArray(Object)} is  called to establish the array to iterate over.
-+     */
-+    public ArrayIterator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs an ArrayIterator that will iterate over the values in the
-+     * specified array.
-+     *
-+     * @param array the array to iterate over.
-+     * @throws IllegalArgumentException if <code>array</code> is not an array.
-+     * @throws NullPointerException     if <code>array</code> is <code>null</code>
-+     */
-+    public ArrayIterator(final Object array) {
-+        super();
-+        setArray(array);
-+    }
-+
-+    /**
-+     * Constructs an ArrayIterator that will iterate over the values in the
-+     * specified array from a specific start index.
-+     *
-+     * @param array      the array to iterate over.
-+     * @param startIndex the index to start iterating at.
-+     * @throws IllegalArgumentException  if <code>array</code> is not an array.
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public ArrayIterator(final Object array, final int startIndex) {
-+        super();
-+        setArray(array);
-+        checkBound(startIndex, "start");
-+        this.startIndex = startIndex;
-+        this.index = startIndex;
-+    }
-+
-+    /**
-+     * Construct an ArrayIterator that will iterate over a range of values
-+     * in the specified array.
-+     *
-+     * @param array      the array to iterate over.
-+     * @param startIndex the index to start iterating at.
-+     * @param endIndex   the index to finish iterating at.
-+     * @throws IllegalArgumentException  if <code>array</code> is not an array.
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     * @throws IndexOutOfBoundsException if either index is invalid
-+     */
-+    public ArrayIterator(final Object array, final int startIndex, final int endIndex) {
-+        super();
-+        setArray(array);
-+        checkBound(startIndex, "start");
-+        checkBound(endIndex, "end");
-+        if (endIndex < startIndex) {
-+            throw new IllegalArgumentException("End index must not be less than start index.");
-+        }
-+        this.startIndex = startIndex;
-+        this.endIndex = endIndex;
-+        this.index = startIndex;
-+    }
-+
-+    /**
-+     * Checks whether the index is valid or not.
-+     *
-+     * @param bound the index to check
-+     * @param type  the index type (for error messages)
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    protected void checkBound(final int bound, final String type) {
-+        if (bound > this.endIndex) {
-+            throw new ArrayIndexOutOfBoundsException("Attempt to make an ArrayIterator that " + type + "s beyond the end of the array. ");
-+        }
-+        if (bound < 0) {
-+            throw new ArrayIndexOutOfBoundsException("Attempt to make an ArrayIterator that " + type + "s before the start of the array. ");
-+        }
-+    }
-+
-+    // Iterator interface
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns true if there are more elements to return from the array.
-+     *
-+     * @return true if there is a next element to return
-+     */
-+    public boolean hasNext() {
-+        return (index < endIndex);
-+    }
-+
-+    /**
-+     * Returns the next element in the array.
-+     *
-+     * @return the next element in the array
-+     * @throws NoSuchElementException if all the elements in the array
-+     *                                have already been returned
-+     */
-+    public E next() {
-+        if (hasNext() == false) {
-+            throw new NoSuchElementException();
-+        }
-+        return (E) Array.get(array, index++);
-+    }
-+
-+    /**
-+     * Throws {@link UnsupportedOperationException}.
-+     *
-+     * @throws UnsupportedOperationException always
-+     */
-+    public void remove() {
-+        throw new UnsupportedOperationException("remove() method is not supported");
-+    }
-+
-+    // Properties
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the array that this iterator is iterating over.
-+     *
-+     * @return the array this iterator iterates over, or <code>null</code> if
-+     *         the no-arg constructor was used and {@link #setArray(Object)} has never
-+     *         been called with a valid array.
-+     */
-+    public Object getArray() {
-+        return array;
-+    }
-+
-+    /**
-+     * Sets the array that the ArrayIterator should iterate over.
-+     * <p/>
-+     * If an array has previously been set (using the single-arg constructor
-+     * or this method) then that array is discarded in favour of this one.
-+     * Iteration is restarted at the start of the new array.
-+     * Although this can be used to reset iteration, the {@link #reset()} method
-+     * is a more effective choice.
-+     *
-+     * @param array the array that the iterator should iterate over.
-+     * @throws IllegalArgumentException if <code>array</code> is not an array.
-+     * @throws NullPointerException     if <code>array</code> is <code>null</code>
-+     */
-+    public void setArray(final Object array) {
-+        // Array.getLength throws IllegalArgumentException if the object is not
-+        // an array or NullPointerException if the object is null.  This call
-+        // is made before saving the array and resetting the index so that the
-+        // array iterator remains in a consistent state if the argument is not
-+        // an array or is null.
-+        this.endIndex = Array.getLength(array);
-+        this.startIndex = 0;
-+        this.array = array;
-+        this.index = 0;
-+    }
-+
-+    /**
-+     * Resets the iterator back to the start index.
-+     */
-+    public void reset() {
-+        this.index = this.startIndex;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/ArrayListIterator.java
-@@ -0,0 +1,210 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableListIterator;
-+
-+import java.lang.reflect.Array;
-+import java.util.ListIterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * Implements a {@link ListIterator} over an array.
-+ * <p/>
-+ * The array can be either an array of object or of primitives. If you know
-+ * that you have an object array, the {@link ObjectArrayListIterator}
-+ * class is a better choice, as it will perform better.
-+ * <p/>
-+ * <p/>
-+ * This iterator does not support {@link #add(Object)} or {@link #remove()}, as the array
-+ * cannot be changed in size. The {@link #set(Object)} method is supported however.
-+ *
-+ * @author Neil O'Toole
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Phil Steitz
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @see org.apache.commons.collections15.iterators.ArrayIterator
-+ * @see java.util.Iterator
-+ * @see java.util.ListIterator
-+ * @since Commons Collections 3.0
-+ */
-+public class ArrayListIterator <E> extends ArrayIterator<E> implements ListIterator<E>, ResettableListIterator<E> {
-+
-+    /**
-+     * Holds the index of the last item returned by a call to <code>next()</code>
-+     * or <code>previous()</code>. This is set to <code>-1</code> if neither method
-+     * has yet been invoked. <code>lastItemIndex</code> is used to to implement
-+     * the {@link #set} method.
-+     */
-+    protected int lastItemIndex = -1;
-+
-+    // Constructors
-+    // ----------------------------------------------------------------------
-+    /**
-+     * Constructor for use with <code>setArray</code>.
-+     * <p/>
-+     * Using this constructor, the iterator is equivalent to an empty iterator
-+     * until {@link #setArray(Object)} is  called to establish the array to iterate over.
-+     */
-+    public ArrayListIterator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs an ArrayListIterator that will iterate over the values in the
-+     * specified array.
-+     *
-+     * @param array the array to iterate over
-+     * @throws IllegalArgumentException if <code>array</code> is not an array.
-+     * @throws NullPointerException     if <code>array</code> is <code>null</code>
-+     */
-+    public ArrayListIterator(Object array) {
-+        super(array);
-+    }
-+
-+    /**
-+     * Constructs an ArrayListIterator that will iterate over the values in the
-+     * specified array from a specific start index.
-+     *
-+     * @param array      the array to iterate over
-+     * @param startIndex the index to start iterating at
-+     * @throws IllegalArgumentException  if <code>array</code> is not an array.
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     * @throws IndexOutOfBoundsException if the start index is out of bounds
-+     */
-+    public ArrayListIterator(Object array, int startIndex) {
-+        super(array, startIndex);
-+        this.startIndex = startIndex;
-+    }
-+
-+    /**
-+     * Construct an ArrayListIterator that will iterate over a range of values
-+     * in the specified array.
-+     *
-+     * @param array      the array to iterate over
-+     * @param startIndex the index to start iterating at
-+     * @param endIndex   the index (exclusive) to finish iterating at
-+     * @throws IllegalArgumentException  if <code>array</code> is not an array.
-+     * @throws IndexOutOfBoundsException if the start or end index is out of bounds
-+     * @throws IllegalArgumentException  if end index is before the start
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     */
-+    public ArrayListIterator(Object array, int startIndex, int endIndex) {
-+        super(array, startIndex, endIndex);
-+        this.startIndex = startIndex;
-+    }
-+
-+    // ListIterator interface
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns true if there are previous elements to return from the array.
-+     *
-+     * @return true if there is a previous element to return
-+     */
-+    public boolean hasPrevious() {
-+        return (this.index > this.startIndex);
-+    }
-+
-+    /**
-+     * Gets the previous element from the array.
-+     *
-+     * @return the previous element
-+     * @throws NoSuchElementException if there is no previous element
-+     */
-+    public E previous() {
-+        if (hasPrevious() == false) {
-+            throw new NoSuchElementException();
-+        }
-+        this.lastItemIndex = --this.index;
-+        return (E) Array.get(this.array, this.index);
-+    }
-+
-+    /**
-+     * Gets the next element from the array.
-+     *
-+     * @return the next element
-+     * @throws NoSuchElementException if there is no next element
-+     */
-+    public E next() {
-+        if (hasNext() == false) {
-+            throw new NoSuchElementException();
-+        }
-+        this.lastItemIndex = this.index;
-+        return (E) Array.get(this.array, this.index++);
-+    }
-+
-+    /**
-+     * Gets the next index to be retrieved.
-+     *
-+     * @return the index of the item to be retrieved next
-+     */
-+    public int nextIndex() {
-+        return this.index - this.startIndex;
-+    }
-+
-+    /**
-+     * Gets the index of the item to be retrieved if {@link #previous()} is called.
-+     *
-+     * @return the index of the item to be retrieved next
-+     */
-+    public int previousIndex() {
-+        return this.index - this.startIndex - 1;
-+    }
-+
-+    /**
-+     * This iterator does not support modification of its backing collection, and so will
-+     * always throw an {@link UnsupportedOperationException} when this method is invoked.
-+     *
-+     * @throws UnsupportedOperationException always thrown.
-+     * @see java.util.ListIterator#set
-+     */
-+    public void add(E o) {
-+        throw new UnsupportedOperationException("add() method is not supported");
-+    }
-+
-+    /**
-+     * Sets the element under the cursor.
-+     * <p/>
-+     * This method sets the element that was returned by the last call
-+     * to {@link #next()} of {@link #previous()}.
-+     * <p/>
-+     * <b>Note:</b> {@link ListIterator} implementations that support
-+     * <code>add()</code> and <code>remove()</code> only allow <code>set()</code> to be called
-+     * once per call to <code>next()</code> or <code>previous</code> (see the {@link ListIterator}
-+     * javadoc for more details). Since this implementation does
-+     * not support <code>add()</code> or <code>remove()</code>, <code>set()</code> may be
-+     * called as often as desired.
-+     *
-+     * @see java.util.ListIterator#set
-+     */
-+    public void set(E o) {
-+        if (this.lastItemIndex == -1) {
-+            throw new IllegalStateException("must call next() or previous() before a call to set()");
-+        }
-+
-+        Array.set(this.array, this.lastItemIndex, o);
-+    }
-+
-+    /**
-+     * Resets the iterator back to the start index.
-+     */
-+    public void reset() {
-+        super.reset();
-+        this.lastItemIndex = -1;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/CollatingIterator.java
-@@ -0,0 +1,374 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.list.UnmodifiableList;
-+
-+import java.util.*;
-+
-+/**
-+ * Provides an ordered iteration over the elements contained in
-+ * a collection of ordered Iterators.
-+ * <p/>
-+ * Given two ordered {@link Iterator} instances <code>A</code> and <code>B</code>,
-+ * the {@link #next} method on this iterator will return the lesser of
-+ * <code>A.next()</code> and <code>B.next()</code>.
-+ *
-+ * @author Rodney Waldhoff
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.1
-+ */
-+public class CollatingIterator <E> implements Iterator<E> {
-+
-+    /**
-+     * The {@link Comparator} used to evaluate order.
-+     */
-+    private Comparator<? super E> comparator = null;
-+
-+    /**
-+     * The list of {@link Iterator}s to evaluate.
-+     */
-+    private ArrayList<Iterator<? extends E>> iterators = null;
-+
-+    /**
-+     * {@link Iterator#next Next} objects peeked from each iterator.
-+     */
-+    private ArrayList<E> values = null;
-+
-+    /**
-+     * Whether or not each {@link #values} element has been set.
-+     */
-+    private BitSet valueSet = null;
-+
-+    /**
-+     * Index of the {@link #iterators iterator} from whom the last returned value was obtained.
-+     */
-+    private int lastReturned = -1;
-+
-+    // Constructors
-+    // ----------------------------------------------------------------------
-+    /**
-+     * Constructs a new <code>CollatingIterator</code>.  Natural sort order
-+     * will be used, and child iterators will have to be manually added
-+     * using the {@link #addIterator(Iterator)} method.
-+     */
-+    public CollatingIterator() {
-+        this(null, 2);
-+    }
-+
-+    /**
-+     * Constructs a new <code>CollatingIterator</code> that will used the
-+     * specified comparator for ordering.  Child iterators will have to be
-+     * manually added using the {@link #addIterator(Iterator)} method.
-+     *
-+     * @param comp the comparator to use to sort, or null to use natural sort order
-+     */
-+    public CollatingIterator(final Comparator<? super E> comp) {
-+        this(comp, 2);
-+    }
-+
-+    /**
-+     * Constructs a new <code>CollatingIterator</code> that will used the
-+     * specified comparator for ordering and have the specified initial
-+     * capacity.  Child iterators will have to be
-+     * manually added using the {@link #addIterator(Iterator)} method.
-+     *
-+     * @param comp             the comparator to use to sort, or null to use natural sort order
-+     * @param initIterCapacity the initial capacity for the internal list
-+     *                         of child iterators
-+     */
-+    public CollatingIterator(final Comparator<? super E> comp, final int initIterCapacity) {
-+        iterators = new ArrayList<Iterator<? extends E>>(initIterCapacity);
-+        setComparator(comp);
-+    }
-+
-+    /**
-+     * Constructs a new <code>CollatingIterator</code> that will use the
-+     * specified comparator to provide ordered iteration over the two
-+     * given iterators.
-+     *
-+     * @param comp the comparator to use to sort, or null to use natural sort order
-+     * @param a    the first child ordered iterator
-+     * @param b    the second child ordered iterator
-+     * @throws NullPointerException if either iterator is null
-+     */
-+    public CollatingIterator(final Comparator<? super E> comp, final Iterator<? extends E> a, final Iterator<? extends E> b) {
-+        this(comp, 2);
-+        addIterator(a);
-+        addIterator(b);
-+    }
-+
-+    /**
-+     * Constructs a new <code>CollatingIterator</code> that will use the
-+     * specified comparator to provide ordered iteration over the array
-+     * of iterators.
-+     *
-+     * @param comp      the comparator to use to sort, or null to use natural sort order
-+     * @param iterators the array of iterators
-+     * @throws NullPointerException if iterators array is or contains null
-+     */
-+    public CollatingIterator(final Comparator<? super E> comp, final Iterator<? extends E>[] iterators) {
-+        this(comp, iterators.length);
-+        for (int i = 0; i < iterators.length; i++) {
-+            addIterator(iterators[i]);
-+        }
-+    }
-+
-+    /**
-+     * Constructs a new <code>CollatingIterator</code> that will use the
-+     * specified comparator to provide ordered iteration over the collection
-+     * of iterators.
-+     *
-+     * @param comp      the comparator to use to sort, or null to use natural sort order
-+     * @param iterators the collection of iterators
-+     * @throws NullPointerException if the iterators collection is or contains null
-+     * @throws ClassCastException   if the iterators collection contains an
-+     *                              element that's not an {@link Iterator}
-+     */
-+    public CollatingIterator(final Comparator<? super E> comp, final Collection<Iterator<? extends E>> iterators) {
-+        this(comp, iterators.size());
-+        for (Iterator<Iterator<? extends E>> it = iterators.iterator(); it.hasNext();) {
-+            Iterator<? extends E> item = it.next();
-+            addIterator(item);
-+        }
-+    }
-+
-+    // Public Methods
-+    // ----------------------------------------------------------------------
-+    /**
-+     * Adds the given {@link Iterator} to the iterators being collated.
-+     *
-+     * @param iterator the iterator to add to the collation, must not be null
-+     * @throws IllegalStateException if iteration has started
-+     * @throws NullPointerException  if the iterator is null
-+     */
-+    public void addIterator(final Iterator<? extends E> iterator) {
-+        checkNotStarted();
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        iterators.add(iterator);
-+    }
-+
-+    /**
-+     * Sets the iterator at the given index.
-+     *
-+     * @param index    index of the Iterator to replace
-+     * @param iterator Iterator to place at the given index
-+     * @throws IndexOutOfBoundsException if index < 0 or index > size()
-+     * @throws IllegalStateException     if iteration has started
-+     * @throws NullPointerException      if the iterator is null
-+     */
-+    public void setIterator(final int index, final Iterator<? extends E> iterator) {
-+        checkNotStarted();
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        iterators.set(index, iterator);
-+    }
-+
-+    /**
-+     * Gets the list of Iterators (unmodifiable).
-+     *
-+     * @return the unmodifiable list of iterators added
-+     */
-+    public List<Iterator<? extends E>> getIterators() {
-+        return UnmodifiableList.decorate(iterators);
-+    }
-+
-+    /**
-+     * Gets the {@link Comparator} by which collatation occurs.
-+     */
-+    public Comparator<? super E> getComparator() {
-+        return comparator;
-+    }
-+
-+    /**
-+     * Sets the {@link Comparator} by which collation occurs.
-+     *
-+     * @throws IllegalStateException if iteration has started
-+     */
-+    public void setComparator(final Comparator<? super E> comp) {
-+        checkNotStarted();
-+        comparator = comp;
-+    }
-+
-+    // Iterator Methods
-+    // -------------------------------------------------------------------
-+    /**
-+     * Returns <code>true</code> if any child iterator has remaining elements.
-+     *
-+     * @return true if this iterator has remaining elements
-+     */
-+    public boolean hasNext() {
-+        start();
-+        return anyValueSet(valueSet) || anyHasNext(iterators);
-+    }
-+
-+    /**
-+     * Returns the next ordered element from a child iterator.
-+     *
-+     * @return the next ordered element
-+     * @throws NoSuchElementException if no child iterator has any more elements
-+     */
-+    public E next() throws NoSuchElementException {
-+        if (hasNext() == false) {
-+            throw new NoSuchElementException();
-+        }
-+        int leastIndex = least();
-+        if (leastIndex == -1) {
-+            throw new NoSuchElementException();
-+        } else {
-+            E val = values.get(leastIndex);
-+            clear(leastIndex);
-+            lastReturned = leastIndex;
-+            return val;
-+        }
-+    }
-+
-+    /**
-+     * Removes the last returned element from the child iterator that
-+     * produced it.
-+     *
-+     * @throws IllegalStateException if there is no last returned element,
-+     *                               or if the last returned element has already been removed
-+     */
-+    public void remove() {
-+        if (lastReturned == -1) {
-+            throw new IllegalStateException("No value can be removed at present");
-+        }
-+        Iterator<? extends E> it = iterators.get(lastReturned);
-+        it.remove();
-+    }
-+
-+    // Private Methods
-+    // -------------------------------------------------------------------
-+    /**
-+     * Initializes the collating state if it hasn't been already.
-+     */
-+    private void start() {
-+        if (values == null) {
-+            values = new ArrayList<E>(iterators.size());
-+            valueSet = new BitSet(iterators.size());
-+            for (int i = 0; i < iterators.size(); i++) {
-+                values.add(null);
-+                valueSet.clear(i);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Sets the {@link #values} and {@link #valueSet} attributes
-+     * at position <i>i</i> to the next value of the
-+     * {@link #iterators iterator} at position <i>i</i>, or
-+     * clear them if the <i>i</i><sup>th</sup> iterator
-+     * has no next value.
-+     *
-+     * @return <tt>false</tt> iff there was no value to set
-+     */
-+    private boolean set(int i) {
-+        Iterator<? extends E> it = iterators.get(i);
-+        if (it.hasNext()) {
-+            values.set(i, it.next());
-+            valueSet.set(i);
-+            return true;
-+        } else {
-+            values.set(i, null);
-+            valueSet.clear(i);
-+            return false;
-+        }
-+    }
-+
-+    /**
-+     * Clears the {@link #values} and {@link #valueSet} attributes
-+     * at position <i>i</i>.
-+     */
-+    private void clear(int i) {
-+        values.set(i, null);
-+        valueSet.clear(i);
-+    }
-+
-+    /**
-+     * Throws {@link IllegalStateException} if iteration has started
-+     * via {@link #start}.
-+     *
-+     * @throws IllegalStateException if iteration started
-+     */
-+    private void checkNotStarted() throws IllegalStateException {
-+        if (values != null) {
-+            throw new IllegalStateException("Can't do that after next or hasNext has been called.");
-+        }
-+    }
-+
-+    /**
-+     * Returns the index of the least element in {@link #values},
-+     * {@link #set(int) setting} any uninitialized values.
-+     *
-+     * @throws IllegalStateException
-+     */
-+    private int least() {
-+        int leastIndex = -1;
-+        E leastObject = null;
-+        for (int i = 0; i < values.size(); i++) {
-+            if (valueSet.get(i) == false) {
-+                set(i);
-+            }
-+            if (valueSet.get(i)) {
-+                if (leastIndex == -1) {
-+                    leastIndex = i;
-+                    leastObject = values.get(i);
-+                } else {
-+                    E curObject = values.get(i);
-+                    if (comparator.compare(curObject, leastObject) < 0) {
-+                        leastObject = curObject;
-+                        leastIndex = i;
-+                    }
-+                }
-+            }
-+        }
-+        return leastIndex;
-+    }
-+
-+    /**
-+     * Returns <code>true</code> iff any bit in the given set is
-+     * <code>true</code>.
-+     */
-+    private boolean anyValueSet(BitSet set) {
-+        for (int i = 0; i < set.size(); i++) {
-+            if (set.get(i)) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Returns <code>true</code> iff any {@link Iterator}
-+     * in the given list has a next value.
-+     */
-+    private boolean anyHasNext(ArrayList<Iterator<? extends E>> iters) {
-+        for (int i = 0; i < iters.size(); i++) {
-+            Iterator<? extends E> it = iters.get(i);
-+            if (it.hasNext()) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/EmptyIterator.java
-@@ -0,0 +1,60 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * Provides an implementation of an empty iterator.
-+ * <p/>
-+ * This class provides an implementation of an empty iterator.
-+ * This class provides for binary compatability between Commons Collections
-+ * 2.1.1 and 3.1 due to issues with <code>IteratorUtils</code>.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.1.1 and 3.1
-+ */
-+public class EmptyIterator <E> extends AbstractEmptyIterator<E> implements ResettableIterator<E> {
-+
-+    /**
-+     * Singleton instance of the iterator.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    public static final ResettableIterator RESETTABLE_INSTANCE = new EmptyIterator();
-+    /**
-+     * Singleton instance of the iterator.
-+     *
-+     * @since Commons Collections 2.1.1 and 3.1
-+     */
-+    public static final Iterator INSTANCE = RESETTABLE_INSTANCE;
-+
-+	public static <T> Iterator<T> getInstance() {
-+		return INSTANCE;
-+	}
-+	
-+    /**
-+     * Constructor.
-+     */
-+    protected EmptyIterator() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/EmptyListIterator.java
-@@ -0,0 +1,56 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableListIterator;
-+
-+import java.util.ListIterator;
-+
-+/**
-+ * Provides an implementation of an empty list iterator.
-+ * <p/>
-+ * This class provides an implementation of an empty list iterator.
-+ * This class provides for binary compatability between Commons Collections
-+ * 2.1.1 and 3.1 due to issues with <code>IteratorUtils</code>.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.1.1 and 3.1
-+ */
-+public class EmptyListIterator <E> extends AbstractEmptyIterator<E> implements ResettableListIterator<E> {
-+
-+    /**
-+     * Singleton instance of the iterator.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    public static final ResettableListIterator RESETTABLE_INSTANCE = new EmptyListIterator();
-+    /**
-+     * Singleton instance of the iterator.
-+     *
-+     * @since Commons Collections 2.1.1 and 3.1
-+     */
-+    public static final ListIterator INSTANCE = RESETTABLE_INSTANCE;
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected EmptyListIterator() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/EmptyMapIterator.java
-@@ -0,0 +1,45 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+/**
-+ * Provides an implementation of an empty map iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.1
-+ */
-+public class EmptyMapIterator extends AbstractEmptyIterator implements MapIterator, ResettableIterator {
-+
-+    /**
-+     * Singleton instance of the iterator.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    public static final MapIterator INSTANCE = new EmptyMapIterator();
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected EmptyMapIterator() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/EmptyOrderedIterator.java
-@@ -0,0 +1,45 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.OrderedIterator;
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+/**
-+ * Provides an implementation of an empty ordered iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.1
-+ */
-+public class EmptyOrderedIterator <E> extends AbstractEmptyIterator<E> implements OrderedIterator<E>, ResettableIterator<E> {
-+
-+    /**
-+     * Singleton instance of the iterator.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    public static final OrderedIterator INSTANCE = new EmptyOrderedIterator();
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected EmptyOrderedIterator() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/EmptyOrderedMapIterator.java
-@@ -0,0 +1,45 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.OrderedMapIterator;
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+/**
-+ * Provides an implementation of an empty ordered map iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.1
-+ */
-+public class EmptyOrderedMapIterator extends AbstractEmptyIterator implements OrderedMapIterator, ResettableIterator {
-+
-+    /**
-+     * Singleton instance of the iterator.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    public static final OrderedMapIterator INSTANCE = new EmptyOrderedMapIterator();
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected EmptyOrderedMapIterator() {
-+        super();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/EntrySetMapIterator.java
-@@ -0,0 +1,171 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+import java.util.Iterator;
-+import java.util.Map;
-+
-+/**
-+ * Implements a <code>MapIterator</code> using a Map entrySet.
-+ * Reverse iteration is not supported.
-+ * <pre>
-+ * MapIterator it = map.mapIterator();
-+ * while (it.hasNext()) {
-+ *   Object key = it.next();
-+ *   Object value = it.getValue();
-+ *   it.setValue(newValue);
-+ * }
-+ * </pre>
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class EntrySetMapIterator <K,V> implements MapIterator<K, V>, ResettableIterator<K> {
-+
-+    private final Map<K, V> map;
-+    private Iterator<Map.Entry<K, V>> iterator;
-+    private Map.Entry<K, V> last;
-+    private boolean canRemove = false;
-+
-+    /**
-+     * Constructor.
-+     *
-+     * @param map the map to iterate over
-+     */
-+    public EntrySetMapIterator(Map<K, V> map) {
-+        super();
-+        this.map = map;
-+        this.iterator = map.entrySet().iterator();
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Checks to see if there are more entries still to be iterated.
-+     *
-+     * @return <code>true</code> if the iterator has more elements
-+     */
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    /**
-+     * Gets the next <em>key</em> from the <code>Map</code>.
-+     *
-+     * @return the next key in the iteration
-+     * @throws java.util.NoSuchElementException
-+     *          if the iteration is finished
-+     */
-+    public K next() {
-+        last = iterator.next();
-+        canRemove = true;
-+        return last.getKey();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Removes the last returned key from the underlying <code>Map</code>.
-+     * <p/>
-+     * This method can be called once per call to <code>next()</code>.
-+     *
-+     * @throws UnsupportedOperationException if remove is not supported by the map
-+     * @throws IllegalStateException         if <code>next()</code> has not yet been called
-+     * @throws IllegalStateException         if <code>remove()</code> has already been called
-+     *                                       since the last call to <code>next()</code>
-+     */
-+    public void remove() {
-+        if (canRemove == false) {
-+            throw new IllegalStateException("Iterator remove() can only be called once after next()");
-+        }
-+        iterator.remove();
-+        last = null;
-+        canRemove = false;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the current key, which is the key returned by the last call
-+     * to <code>next()</code>.
-+     *
-+     * @return the current key
-+     * @throws IllegalStateException if <code>next()</code> has not yet been called
-+     */
-+    public K getKey() {
-+        if (last == null) {
-+            throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
-+        }
-+        return last.getKey();
-+    }
-+
-+    /**
-+     * Gets the current value, which is the value associated with the last key
-+     * returned by <code>next()</code>.
-+     *
-+     * @return the current value
-+     * @throws IllegalStateException if <code>next()</code> has not yet been called
-+     */
-+    public V getValue() {
-+        if (last == null) {
-+            throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
-+        }
-+        return last.getValue();
-+    }
-+
-+    /**
-+     * Sets the value associated with the current key.
-+     *
-+     * @param value the new value
-+     * @return the previous value
-+     * @throws UnsupportedOperationException if setValue is not supported by the map
-+     * @throws IllegalStateException         if <code>next()</code> has not yet been called
-+     * @throws IllegalStateException         if <code>remove()</code> has been called since the
-+     *                                       last call to <code>next()</code>
-+     */
-+    public V setValue(V value) {
-+        if (last == null) {
-+            throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
-+        }
-+        return last.setValue(value);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Resets the state of the iterator.
-+     */
-+    public void reset() {
-+        iterator = map.entrySet().iterator();
-+        last = null;
-+        canRemove = false;
-+    }
-+
-+    /**
-+     * Gets the iterator as a String.
-+     *
-+     * @return a string version of the iterator
-+     */
-+    public String toString() {
-+        if (last != null) {
-+            return "MapIterator[" + getKey() + "=" + getValue() + "]";
-+        } else {
-+            return "MapIterator[]";
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/EnumerationIterator.java
-@@ -0,0 +1,146 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import java.util.Collection;
-+import java.util.Enumeration;
-+import java.util.Iterator;
-+
-+/**
-+ * Adapter to make {@link Enumeration Enumeration} instances appear
-+ * to be {@link Iterator Iterator} instances.
-+ *
-+ * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
-+ * @author Matt Hall, John Watkinson, <a href="mailto:dlr at finemaltcoding.com">Daniel Rall</a>
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 1.0
-+ */
-+public class EnumerationIterator <E> implements Iterator<E> {
-+
-+    /**
-+     * The collection to remove elements from
-+     */
-+    private Collection<E> collection;
-+    /**
-+     * The enumeration being converted
-+     */
-+    private Enumeration<E> enumeration;
-+    /**
-+     * The last object retrieved
-+     */
-+    private E last;
-+    
-+    // Constructors
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new <code>EnumerationIterator</code> that will not
-+     * function until {@link #setEnumeration(Enumeration)} is called.
-+     */
-+    public EnumerationIterator() {
-+        this(null, null);
-+    }
-+
-+    /**
-+     * Constructs a new <code>EnumerationIterator</code> that provides
-+     * an iterator view of the given enumeration.
-+     *
-+     * @param enumeration the enumeration to use
-+     */
-+    public EnumerationIterator(final Enumeration<E> enumeration) {
-+        this(enumeration, null);
-+    }
-+
-+    /**
-+     * Constructs a new <code>EnumerationIterator</code> that will remove
-+     * elements from the specified collection.
-+     *
-+     * @param enumeration the enumeration to use
-+     * @param collection  the collection to remove elements form
-+     */
-+    public EnumerationIterator(final Enumeration<E> enumeration, final Collection<E> collection) {
-+        super();
-+        this.enumeration = enumeration;
-+        this.collection = collection;
-+        this.last = null;
-+    }
-+
-+    // Iterator interface
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns true if the underlying enumeration has more elements.
-+     *
-+     * @return true if the underlying enumeration has more elements
-+     * @throws NullPointerException if the underlying enumeration is null
-+     */
-+    public boolean hasNext() {
-+        return enumeration.hasMoreElements();
-+    }
-+
-+    /**
-+     * Returns the next object from the enumeration.
-+     *
-+     * @return the next object from the enumeration
-+     * @throws NullPointerException if the enumeration is null
-+     */
-+    public E next() {
-+        last = enumeration.nextElement();
-+        return last;
-+    }
-+
-+    /**
-+     * Removes the last retrieved element if a collection is attached.
-+     * <p/>
-+     * Functions if an associated <code>Collection</code> is known.
-+     * If so, the first occurrence of the last returned object from this
-+     * iterator will be removed from the collection.
-+     *
-+     * @throws IllegalStateException         <code>next()</code> not called.
-+     * @throws UnsupportedOperationException if no associated collection
-+     */
-+    public void remove() {
-+        if (collection != null) {
-+            if (last != null) {
-+                collection.remove(last);
-+            } else {
-+                throw new IllegalStateException("next() must have been called for remove() to function");
-+            }
-+        } else {
-+            throw new UnsupportedOperationException("No Collection associated with this Iterator");
-+        }
-+    }
-+
-+    // Properties
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the underlying enumeration.
-+     *
-+     * @return the underlying enumeration
-+     */
-+    public Enumeration<E> getEnumeration() {
-+        return enumeration;
-+    }
-+
-+    /**
-+     * Sets the underlying enumeration.
-+     *
-+     * @param enumeration the new underlying enumeration
-+     */
-+    public void setEnumeration(final Enumeration<E> enumeration) {
-+        this.enumeration = enumeration;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/FilterIterator.java
-@@ -0,0 +1,192 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.util.Iterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * Decorates an iterator such that only elements matching a predicate filter
-+ * are returned.
-+ *
-+ * @author James Strachan
-+ * @author Jan Sorensen
-+ * @author Ralph Wagner
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 1.0
-+ */
-+public class FilterIterator <E> implements Iterator<E> {
-+
-+    /**
-+     * The iterator being used
-+     */
-+    private Iterator<E> iterator;
-+    /**
-+     * The predicate being used
-+     */
-+    private Predicate<? super E> predicate;
-+    /**
-+     * The next object in the iteration
-+     */
-+    private E nextObject;
-+    /**
-+     * Whether the next object has been calculated yet
-+     */
-+    private boolean nextObjectSet = false;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new <code>FilterIterator</code> that will not function
-+     * until {@link #setIterator(Iterator) setIterator} is invoked.
-+     */
-+    public FilterIterator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new <code>FilterIterator</code> that will not function
-+     * until {@link #setPredicate(Predicate) setPredicate} is invoked.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public FilterIterator(Iterator<E> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    /**
-+     * Constructs a new <code>FilterIterator</code> that will use the
-+     * given iterator and predicate.
-+     *
-+     * @param iterator  the iterator to use
-+     * @param predicate the predicate to use
-+     */
-+    public FilterIterator(Iterator<E> iterator, Predicate<? super E> predicate) {
-+        super();
-+        this.iterator = iterator;
-+        this.predicate = predicate;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns true if the underlying iterator contains an object that
-+     * matches the predicate.
-+     *
-+     * @return true if there is another object that matches the predicate
-+     */
-+    public boolean hasNext() {
-+        if (nextObjectSet) {
-+            return true;
-+        } else {
-+            return setNextObject();
-+        }
-+    }
-+
-+    /**
-+     * Returns the next object that matches the predicate.
-+     *
-+     * @return the next object which matches the given predicate
-+     * @throws NoSuchElementException if there are no more elements that
-+     *                                match the predicate
-+     */
-+    public E next() {
-+        if (!nextObjectSet) {
-+            if (!setNextObject()) {
-+                throw new NoSuchElementException();
-+            }
-+        }
-+        nextObjectSet = false;
-+        return nextObject;
-+    }
-+
-+    /**
-+     * Removes from the underlying collection of the base iterator the last
-+     * element returned by this iterator.
-+     * This method can only be called
-+     * if <code>next()</code> was called, but not after
-+     * <code>hasNext()</code>, because the <code>hasNext()</code> call
-+     * changes the base iterator.
-+     *
-+     * @throws IllegalStateException if <code>hasNext()</code> has already
-+     *                               been called.
-+     */
-+    public void remove() {
-+        if (nextObjectSet) {
-+            throw new IllegalStateException("remove() cannot be called");
-+        }
-+        iterator.remove();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the iterator this iterator is using.
-+     *
-+     * @return the iterator.
-+     */
-+    public Iterator<E> getIterator() {
-+        return iterator;
-+    }
-+
-+    /**
-+     * Sets the iterator for this iterator to use.
-+     * If iteration has started, this effectively resets the iterator.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public void setIterator(Iterator<E> iterator) {
-+        this.iterator = iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the predicate this iterator is using.
-+     *
-+     * @return the predicate.
-+     */
-+    public Predicate<? super E> getPredicate() {
-+        return predicate;
-+    }
-+
-+    /**
-+     * Sets the predicate this the iterator to use.
-+     *
-+     * @param predicate the transformer to use
-+     */
-+    public void setPredicate(Predicate<? super E> predicate) {
-+        this.predicate = predicate;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Set nextObject to the next object. If there are no more
-+     * objects then return false. Otherwise, return true.
-+     */
-+    private boolean setNextObject() {
-+        while (iterator.hasNext()) {
-+            E object = iterator.next();
-+            if (predicate.evaluate(object)) {
-+                nextObject = object;
-+                nextObjectSet = true;
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/FilterListIterator.java
-@@ -0,0 +1,290 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.util.ListIterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * A proxy {@link ListIterator ListIterator} which
-+ * takes a {@link Predicate Predicate} instance to filter
-+ * out objects from an underlying <code>ListIterator</code>
-+ * instance. Only objects for which the specified
-+ * <code>Predicate</code> evaluates to <code>true</code> are
-+ * returned by the iterator.
-+ *
-+ * @author Matt Hall, John Watkinson, Rodney Waldhoff
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.0
-+ */
-+public class FilterListIterator <E> implements ListIterator<E> {
-+
-+    /**
-+     * The iterator being used
-+     */
-+    private ListIterator<E> iterator;
-+
-+    /**
-+     * The predicate being used
-+     */
-+    private Predicate<? super E> predicate;
-+
-+    /**
-+     * The value of the next (matching) object, when
-+     * {@link #nextObjectSet} is true.
-+     */
-+    private E nextObject;
-+
-+    /**
-+     * Whether or not the {@link #nextObject} has been set
-+     * (possibly to <code>null</code>).
-+     */
-+    private boolean nextObjectSet = false;
-+
-+    /**
-+     * The value of the previous (matching) object, when
-+     * {@link #previousObjectSet} is true.
-+     */
-+    private E previousObject;
-+
-+    /**
-+     * Whether or not the {@link #previousObject} has been set
-+     * (possibly to <code>null</code>).
-+     */
-+    private boolean previousObjectSet = false;
-+
-+    /**
-+     * The index of the element that would be returned by {@link #next}.
-+     */
-+    private int nextIndex = 0;
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new <code>FilterListIterator</code> that will not
-+     * function until
-+     * {@link #setPredicate(Predicate) setPredicate} is invoked.
-+     */
-+    public FilterListIterator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new <code>FilterListIterator</code> that will not
-+     * function until {@link #setPredicate(Predicate) setPredicate} is invoked.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public FilterListIterator(ListIterator<E> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    /**
-+     * Constructs a new <code>FilterListIterator</code>.
-+     *
-+     * @param iterator  the iterator to use
-+     * @param predicate the predicate to use
-+     */
-+    public FilterListIterator(ListIterator<E> iterator, Predicate<? super E> predicate) {
-+        super();
-+        this.iterator = iterator;
-+        this.predicate = predicate;
-+    }
-+
-+    /**
-+     * Constructs a new <code>FilterListIterator</code>.
-+     *
-+     * @param predicate the predicate to use.
-+     */
-+    public FilterListIterator(Predicate<? super E> predicate) {
-+        super();
-+        this.predicate = predicate;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Not supported.
-+     */
-+    public void add(E o) {
-+        throw new UnsupportedOperationException("FilterListIterator.add(Object) is not supported.");
-+    }
-+
-+    public boolean hasNext() {
-+        if (nextObjectSet) {
-+            return true;
-+        } else {
-+            return setNextObject();
-+        }
-+    }
-+
-+    public boolean hasPrevious() {
-+        if (previousObjectSet) {
-+            return true;
-+        } else {
-+            return setPreviousObject();
-+        }
-+    }
-+
-+    public E next() {
-+        if (!nextObjectSet) {
-+            if (!setNextObject()) {
-+                throw new NoSuchElementException();
-+            }
-+        }
-+        nextIndex++;
-+        E temp = nextObject;
-+        clearNextObject();
-+        return temp;
-+    }
-+
-+    public int nextIndex() {
-+        return nextIndex;
-+    }
-+
-+    public E previous() {
-+        if (!previousObjectSet) {
-+            if (!setPreviousObject()) {
-+                throw new NoSuchElementException();
-+            }
-+        }
-+        nextIndex--;
-+        E temp = previousObject;
-+        clearPreviousObject();
-+        return temp;
-+    }
-+
-+    public int previousIndex() {
-+        return (nextIndex - 1);
-+    }
-+
-+    /**
-+     * Not supported.
-+     */
-+    public void remove() {
-+        throw new UnsupportedOperationException("FilterListIterator.remove() is not supported.");
-+    }
-+
-+    /**
-+     * Not supported.
-+     */
-+    public void set(E o) {
-+        throw new UnsupportedOperationException("FilterListIterator.set(Object) is not supported.");
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the iterator this iterator is using.
-+     *
-+     * @return the iterator.
-+     */
-+    public ListIterator<E> getListIterator() {
-+        return iterator;
-+    }
-+
-+    /**
-+     * Sets the iterator for this iterator to use.
-+     * If iteration has started, this effectively resets the iterator.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public void setListIterator(ListIterator<E> iterator) {
-+        this.iterator = iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the predicate this iterator is using.
-+     *
-+     * @return the predicate.
-+     */
-+    public Predicate<? super E> getPredicate() {
-+        return predicate;
-+    }
-+
-+    /**
-+     * Sets the predicate this the iterator to use.
-+     *
-+     * @param predicate the transformer to use
-+     */
-+    public void setPredicate(Predicate<? super E> predicate) {
-+        this.predicate = predicate;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    private void clearNextObject() {
-+        nextObject = null;
-+        nextObjectSet = false;
-+    }
-+
-+    private boolean setNextObject() {
-+        // if previousObjectSet,
-+        // then we've walked back one step in the 
-+        // underlying list (due to a hasPrevious() call)
-+        // so skip ahead one matching object
-+        if (previousObjectSet) {
-+            clearPreviousObject();
-+            if (!setNextObject()) {
-+                return false;
-+            } else {
-+                clearNextObject();
-+            }
-+        }
-+
-+        while (iterator.hasNext()) {
-+            E object = iterator.next();
-+            if (predicate.evaluate(object)) {
-+                nextObject = object;
-+                nextObjectSet = true;
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    private void clearPreviousObject() {
-+        previousObject = null;
-+        previousObjectSet = false;
-+    }
-+
-+    private boolean setPreviousObject() {
-+        // if nextObjectSet,
-+        // then we've walked back one step in the 
-+        // underlying list (due to a hasNext() call)
-+        // so skip ahead one matching object
-+        if (nextObjectSet) {
-+            clearNextObject();
-+            if (!setPreviousObject()) {
-+                return false;
-+            } else {
-+                clearPreviousObject();
-+            }
-+        }
-+
-+        while (iterator.hasPrevious()) {
-+            E object = iterator.previous();
-+            if (predicate.evaluate(object)) {
-+                previousObject = object;
-+                previousObjectSet = true;
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/IteratorChain.java
-@@ -0,0 +1,293 @@
-+// GenericsNote: Converted.
-+// GenericsNote: Some questions about things like UnmodifiableList.decorate(iteratorChain); and so on
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.list.UnmodifiableList;
-+
-+import java.util.ArrayList;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.List;
-+
-+/**
-+ * An IteratorChain is an Iterator that wraps a number of Iterators.
-+ * <p/>
-+ * This class makes multiple iterators look like one to the caller
-+ * When any method from the Iterator interface is called, the IteratorChain
-+ * will delegate to a single underlying Iterator. The IteratorChain will
-+ * invoke the Iterators in sequence until all Iterators are exhausted.
-+ * <p/>
-+ * Under many circumstances, linking Iterators together in this manner is
-+ * more efficient (and convenient) than reading out the contents of each
-+ * Iterator into a List and creating a new Iterator.
-+ * <p/>
-+ * Calling a method that adds new Iterator<i>after a method in the Iterator
-+ * interface has been called</i> will result in an UnsupportedOperationException.
-+ * Subclasses should <i>take care</i> to not alter the underlying List of Iterators.
-+ * <p/>
-+ * NOTE: As from version 3.0, the IteratorChain may contain no
-+ * iterators. In this case the class will function as an empty iterator.
-+ *
-+ * @author Morgan Delagrange
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.1
-+ */
-+public class IteratorChain <E> implements Iterator<E> {
-+
-+    /**
-+     * The chain of iterators
-+     */
-+    protected final List<Iterator<? extends E>> iteratorChain = new ArrayList<Iterator<? extends E>>();
-+    /**
-+     * The index of the current iterator
-+     */
-+    protected int currentIteratorIndex = 0;
-+    /**
-+     * The current iterator
-+     */
-+    protected Iterator<? extends E> currentIterator = null;
-+    /**
-+     * The "last used" Iterator is the Iterator upon which
-+     * next() or hasNext() was most recently called
-+     * used for the remove() operation only
-+     */
-+    protected Iterator<? extends E> lastUsedIterator = null;
-+    /**
-+     * ComparatorChain is "locked" after the first time
-+     * compare(Object,Object) is called
-+     */
-+    protected boolean isLocked = false;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Construct an IteratorChain with no Iterators.
-+     * <p/>
-+     * You will normally use {@link #addIterator(Iterator)} to add
-+     * some iterators after using this constructor.
-+     */
-+    public IteratorChain() {
-+        super();
-+    }
-+
-+    /**
-+     * Construct an IteratorChain with a single Iterator.
-+     *
-+     * @param iterator first Iterator in the IteratorChain
-+     * @throws NullPointerException if the iterator is null
-+     */
-+    public IteratorChain(Iterator<? extends E> iterator) {
-+        super();
-+        addIterator(iterator);
-+    }
-+
-+    /**
-+     * Constructs a new <code>IteratorChain</code> over the two
-+     * given iterators.
-+     *
-+     * @param a the first child iterator
-+     * @param b the second child iterator
-+     * @throws NullPointerException if either iterator is null
-+     */
-+    public IteratorChain(Iterator<? extends E> a, Iterator<? extends E> b) {
-+        super();
-+        addIterator(a);
-+        addIterator(b);
-+    }
-+
-+    /**
-+     * Constructs a new <code>IteratorChain</code> over the array
-+     * of iterators.
-+     *
-+     * @param iterators the array of iterators
-+     * @throws NullPointerException if iterators array is or contains null
-+     */
-+    public IteratorChain(Iterator<? extends E>[] iterators) {
-+        super();
-+        for (int i = 0; i < iterators.length; i++) {
-+            addIterator(iterators[i]);
-+        }
-+    }
-+
-+    /**
-+     * Constructs a new <code>IteratorChain</code> over the collection
-+     * of iterators.
-+     *
-+     * @param iterators the collection of iterators
-+     * @throws NullPointerException if iterators collection is or contains null
-+     * @throws ClassCastException   if iterators collection doesn't contain an iterator
-+     */
-+    public IteratorChain(Collection<Iterator<? extends E>> iterators) {
-+        super();
-+        for (Iterator<? extends E> iterator : iterators) {
-+            addIterator(iterator);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Add an Iterator to the end of the chain
-+     *
-+     * @param iterator Iterator to add
-+     * @throws IllegalStateException if I've already started iterating
-+     * @throws NullPointerException  if the iterator is null
-+     */
-+    public void addIterator(Iterator<? extends E> iterator) {
-+        checkLocked();
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        iteratorChain.add(iterator);
-+    }
-+
-+    /**
-+     * Set the Iterator at the given index
-+     *
-+     * @param index    index of the Iterator to replace
-+     * @param iterator Iterator to place at the given index
-+     * @throws IndexOutOfBoundsException if index < 0 or index > size()
-+     * @throws IllegalStateException     if I've already started iterating
-+     * @throws NullPointerException      if the iterator is null
-+     */
-+    public void setIterator(int index, Iterator<? extends E> iterator) throws IndexOutOfBoundsException {
-+        checkLocked();
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        iteratorChain.set(index, iterator);
-+    }
-+
-+    /**
-+     * Get the list of Iterators (unmodifiable)
-+     *
-+     * @return the unmodifiable list of iterators added
-+     */
-+    public List<Iterator<? extends E>> getIterators() {
-+        return UnmodifiableList.decorate(iteratorChain);
-+    }
-+
-+    /**
-+     * Number of Iterators in the current IteratorChain.
-+     *
-+     * @return Iterator count
-+     */
-+    public int size() {
-+        return iteratorChain.size();
-+    }
-+
-+    /**
-+     * Determine if modifications can still be made to the IteratorChain.
-+     * IteratorChains cannot be modified once they have executed a method
-+     * from the Iterator interface.
-+     *
-+     * @return true if IteratorChain cannot be modified, false if it can
-+     */
-+    public boolean isLocked() {
-+        return isLocked;
-+    }
-+
-+    /**
-+     * Checks whether the iterator chain is now locked and in use.
-+     */
-+    private void checkLocked() {
-+        if (isLocked == true) {
-+            throw new UnsupportedOperationException("IteratorChain cannot be changed after the first use of a method from the Iterator interface");
-+        }
-+    }
-+
-+    /**
-+     * Lock the chain so no more iterators can be added.
-+     * This must be called from all Iterator interface methods.
-+     */
-+    private void lockChain() {
-+        if (isLocked == false) {
-+            isLocked = true;
-+        }
-+    }
-+
-+    /**
-+     * Updates the current iterator field to ensure that the current Iterator
-+     * is not exhausted
-+     */
-+    protected void updateCurrentIterator() {
-+        if (currentIterator == null) {
-+            if (iteratorChain.isEmpty()) {
-+                currentIterator = EmptyIterator.INSTANCE;
-+            } else {
-+                currentIterator = iteratorChain.get(0);
-+            }
-+            // set last used iterator here, in case the user calls remove
-+            // before calling hasNext() or next() (although they shouldn't)
-+            lastUsedIterator = currentIterator;
-+        }
-+
-+        while (currentIterator.hasNext() == false && currentIteratorIndex < iteratorChain.size() - 1) {
-+            currentIteratorIndex++;
-+            currentIterator = iteratorChain.get(currentIteratorIndex);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Return true if any Iterator in the IteratorChain has a remaining element.
-+     *
-+     * @return true if elements remain
-+     */
-+    public boolean hasNext() {
-+        lockChain();
-+        updateCurrentIterator();
-+        lastUsedIterator = currentIterator;
-+
-+        return currentIterator.hasNext();
-+    }
-+
-+    /**
-+     * Returns the next Object of the current Iterator
-+     *
-+     * @return Object from the current Iterator
-+     * @throws java.util.NoSuchElementException
-+     *          if all the Iterators are exhausted
-+     */
-+    public E next() {
-+        lockChain();
-+        updateCurrentIterator();
-+        lastUsedIterator = currentIterator;
-+
-+        return currentIterator.next();
-+    }
-+
-+    /**
-+     * Removes from the underlying collection the last element
-+     * returned by the Iterator.  As with next() and hasNext(),
-+     * this method calls remove() on the underlying Iterator.
-+     * Therefore, this method may throw an
-+     * UnsupportedOperationException if the underlying
-+     * Iterator does not support this method.
-+     *
-+     * @throws UnsupportedOperationException if the remove operator is not supported by the underlying Iterator
-+     * @throws IllegalStateException         if the next method has not yet been called, or the remove method has
-+     *                                       already been called after the last call to the next method.
-+     */
-+    public void remove() {
-+        lockChain();
-+        updateCurrentIterator();
-+
-+        lastUsedIterator.remove();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/IteratorEnumeration.java
-@@ -0,0 +1,102 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import java.util.Enumeration;
-+import java.util.Iterator;
-+
-+/**
-+ * Adapter to make an {@link Iterator Iterator} instance appear to be
-+ * an {@link Enumeration Enumeration} instance.
-+ *
-+ * @author Matt Hall, John Watkinson, <a href="mailto:jstrachan at apache.org">James Strachan</a>
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 1.0
-+ */
-+public class IteratorEnumeration <E> implements Enumeration<E> {
-+
-+    /**
-+     * The iterator being decorated.
-+     */
-+    private Iterator<E> iterator;
-+
-+    /**
-+     * Constructs a new <code>IteratorEnumeration</code> that will not
-+     * function until {@link #setIterator(Iterator) setIterator} is
-+     * invoked.
-+     */
-+    public IteratorEnumeration() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new <code>IteratorEnumeration</code> that will use
-+     * the given iterator.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public IteratorEnumeration(Iterator<E> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    // Iterator interface
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Returns true if the underlying iterator has more elements.
-+     *
-+     * @return true if the underlying iterator has more elements
-+     */
-+    public boolean hasMoreElements() {
-+        return iterator.hasNext();
-+    }
-+
-+    /**
-+     * Returns the next element from the underlying iterator.
-+     *
-+     * @return the next element from the underlying iterator.
-+     * @throws java.util.NoSuchElementException
-+     *          if the underlying iterator has no
-+     *          more elements
-+     */
-+    public E nextElement() {
-+        return iterator.next();
-+    }
-+
-+    // Properties
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Returns the underlying iterator.
-+     *
-+     * @return the underlying iterator
-+     */
-+    public Iterator<E> getIterator() {
-+        return iterator;
-+    }
-+
-+    /**
-+     * Sets the underlying iterator.
-+     *
-+     * @param iterator the new underlying iterator
-+     */
-+    public void setIterator(Iterator<E> iterator) {
-+        this.iterator = iterator;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/ListIteratorWrapper.java
-@@ -0,0 +1,180 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import java.util.Iterator;
-+import java.util.LinkedList;
-+import java.util.ListIterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * As the wrapped Iterator is traversed, ListIteratorWrapper
-+ * builds a LinkedList of its values, permitting all required
-+ * operations of ListIterator.
-+ *
-+ * @author Morgan Delagrange
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.1
-+ */
-+public class ListIteratorWrapper <E> implements ListIterator<E> {
-+
-+    /**
-+     * Holds value of property "iterator"
-+     */
-+    private final Iterator<E> iterator;
-+    private final LinkedList<E> list = new LinkedList<E>();
-+
-+    // position of this iterator
-+    private int currentIndex = 0;
-+    // position of the wrapped iterator
-+    // this Iterator should only be used to populate the list
-+    private int wrappedIteratorIndex = 0;
-+
-+    private static final String UNSUPPORTED_OPERATION_MESSAGE = "ListIteratorWrapper does not support optional operations of ListIterator.";
-+
-+    // Constructor
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Constructs a new <code>ListIteratorWrapper</code> that will wrap
-+     * the given iterator.
-+     *
-+     * @param iterator the iterator to wrap
-+     * @throws NullPointerException if the iterator is null
-+     */
-+    public ListIteratorWrapper(Iterator<E> iterator) {
-+        super();
-+        if (iterator == null) {
-+            throw new NullPointerException("Iterator must not be null");
-+        }
-+        this.iterator = iterator;
-+    }
-+
-+    // ListIterator interface
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Throws {@link UnsupportedOperationException}.
-+     *
-+     * @param o ignored
-+     * @throws UnsupportedOperationException always
-+     */
-+    public void add(E o) throws UnsupportedOperationException {
-+        throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MESSAGE);
-+    }
-+
-+
-+    /**
-+     * Returns true if there are more elements in the iterator.
-+     *
-+     * @return true if there are more elements
-+     */
-+    public boolean hasNext() {
-+        if (currentIndex == wrappedIteratorIndex) {
-+            return iterator.hasNext();
-+        }
-+
-+        return true;
-+    }
-+
-+    /**
-+     * Returns true if there are previous elements in the iterator.
-+     *
-+     * @return true if there are previous elements
-+     */
-+    public boolean hasPrevious() {
-+        if (currentIndex == 0) {
-+            return false;
-+        }
-+
-+        return true;
-+    }
-+
-+    /**
-+     * Returns the next element from the iterator.
-+     *
-+     * @return the next element from the iterator
-+     * @throws NoSuchElementException if there are no more elements
-+     */
-+    public E next() throws NoSuchElementException {
-+        if (currentIndex < wrappedIteratorIndex) {
-+            ++currentIndex;
-+            return list.get(currentIndex - 1);
-+        }
-+
-+        E retval = iterator.next();
-+        list.add(retval);
-+        ++currentIndex;
-+        ++wrappedIteratorIndex;
-+        return retval;
-+    }
-+
-+    /**
-+     * Returns in the index of the next element.
-+     *
-+     * @return the index of the next element
-+     */
-+    public int nextIndex() {
-+        return currentIndex;
-+    }
-+
-+    /**
-+     * Returns the the previous element.
-+     *
-+     * @return the previous element
-+     * @throws NoSuchElementException if there are no previous elements
-+     */
-+    public E previous() throws NoSuchElementException {
-+        if (currentIndex == 0) {
-+            throw new NoSuchElementException();
-+        }
-+
-+        --currentIndex;
-+        return list.get(currentIndex);
-+    }
-+
-+    /**
-+     * Returns the index of the previous element.
-+     *
-+     * @return the index of the previous element
-+     */
-+    public int previousIndex() {
-+        return currentIndex - 1;
-+    }
-+
-+    /**
-+     * Throws {@link UnsupportedOperationException}.
-+     *
-+     * @throws UnsupportedOperationException always
-+     */
-+    public void remove() throws UnsupportedOperationException {
-+        throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MESSAGE);
-+    }
-+
-+    /**
-+     * Throws {@link UnsupportedOperationException}.
-+     *
-+     * @param o ignored
-+     * @throws UnsupportedOperationException always
-+     */
-+    public void set(E o) throws UnsupportedOperationException {
-+        throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MESSAGE);
-+    }
-+
-+}
-+
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/LoopingIterator.java
-@@ -0,0 +1,130 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * An Iterator that restarts when it reaches the end.
-+ * <p/>
-+ * The iterator will loop continuously around the provided elements, unless
-+ * there are no elements in the collection to begin with, or all the elements
-+ * have been {@link #remove removed}.
-+ * <p/>
-+ * Concurrent modifications are not directly supported, and for most collection
-+ * implementations will throw a ConcurrentModificationException.
-+ *
-+ * @author <a href="mailto:joncrlsn at users.sf.net">Jonathan Carlson</a>
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class LoopingIterator <E> implements ResettableIterator<E> {
-+
-+    /**
-+     * The collection to base the iterator on
-+     */
-+    private Collection<E> collection;
-+    /**
-+     * The current iterator
-+     */
-+    private Iterator<E> iterator;
-+
-+    /**
-+     * Constructor that wraps a collection.
-+     * <p/>
-+     * There is no way to reset an Iterator instance without recreating it from
-+     * the original source, so the Collection must be passed in.
-+     *
-+     * @param coll the collection to wrap
-+     * @throws NullPointerException if the collection is null
-+     */
-+    public LoopingIterator(Collection<E> coll) {
-+        if (coll == null) {
-+            throw new NullPointerException("The collection must not be null");
-+        }
-+        collection = coll;
-+        reset();
-+    }
-+
-+    /**
-+     * Has the iterator any more elements.
-+     * <p/>
-+     * Returns false only if the collection originally had zero elements, or
-+     * all the elements have been {@link #remove removed}.
-+     *
-+     * @return <code>true</code> if there are more elements
-+     */
-+    public boolean hasNext() {
-+        return (collection.size() > 0);
-+    }
-+
-+    /**
-+     * Returns the next object in the collection.
-+     * <p/>
-+     * If at the end of the collection, return the first element.
-+     *
-+     * @throws NoSuchElementException if there are no elements
-+     *                                at all.  Use {@link #hasNext} to avoid this error.
-+     */
-+    public E next() {
-+        if (collection.size() == 0) {
-+            throw new NoSuchElementException("There are no elements for this iterator to loop on");
-+        }
-+        if (iterator.hasNext() == false) {
-+            reset();
-+        }
-+        return iterator.next();
-+    }
-+
-+    /**
-+     * Removes the previously retrieved item from the underlying collection.
-+     * <p/>
-+     * This feature is only supported if the underlying collection's
-+     * {@link Collection#iterator iterator} method returns an implementation
-+     * that supports it.
-+     * <p/>
-+     * This method can only be called after at least one {@link #next} method call.
-+     * After a removal, the remove method may not be called again until another
-+     * next has been performed. If the {@link #reset} is called, then remove may
-+     * not be called until {@link #next} is called again.
-+     */
-+    public void remove() {
-+        iterator.remove();
-+    }
-+
-+    /**
-+     * Resets the iterator back to the start of the collection.
-+     */
-+    public void reset() {
-+        iterator = collection.iterator();
-+    }
-+
-+    /**
-+     * Gets the size of the collection underlying the iterator.
-+     *
-+     * @return the current collection size
-+     */
-+    public int size() {
-+        return collection.size();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/ObjectArrayIterator.java
-@@ -0,0 +1,222 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+import java.util.Iterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * An {@link Iterator} over an array of objects.
-+ * <p/>
-+ * This iterator does not support {@link #remove}, as the object array cannot be
-+ * structurally modified.
-+ * <p/>
-+ * The iterator implements a {@link #reset} method, allowing the reset of the iterator
-+ * back to the start if required.
-+ *
-+ * @author James Strachan
-+ * @author Mauricio S. Moura
-+ * @author Michael A. Smith
-+ * @author Neil O'Toole
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Phil Steitz
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ObjectArrayIterator <E> implements Iterator<E>, ResettableIterator<E> {
-+
-+    /**
-+     * The array
-+     */
-+    protected E[] array = null;
-+    /**
-+     * The start index to loop from
-+     */
-+    protected int startIndex = 0;
-+    /**
-+     * The end index to loop to
-+     */
-+    protected int endIndex = 0;
-+    /**
-+     * The current iterator index
-+     */
-+    protected int index = 0;
-+
-+    /**
-+     * Constructor for use with <code>setArray</code>.
-+     * <p/>
-+     * Using this constructor, the iterator is equivalent to an empty iterator
-+     * until {@link #setArray} is  called to establish the array to iterate over.
-+     */
-+    public ObjectArrayIterator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs an ObjectArrayIterator that will iterate over the values in the
-+     * specified array.
-+     *
-+     * @param array the array to iterate over
-+     * @throws NullPointerException if <code>array</code> is <code>null</code>
-+     */
-+    public ObjectArrayIterator(E[] array) {
-+        this(array, 0, array.length);
-+    }
-+
-+    /**
-+     * Constructs an ObjectArrayIterator that will iterate over the values in the
-+     * specified array from a specific start index.
-+     *
-+     * @param array the array to iterate over
-+     * @param start the index to start iterating at
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     * @throws IndexOutOfBoundsException if the start index is out of bounds
-+     */
-+    public ObjectArrayIterator(E[] array, int start) {
-+        this(array, start, array.length);
-+    }
-+
-+    /**
-+     * Construct an ObjectArrayIterator that will iterate over a range of values
-+     * in the specified array.
-+     *
-+     * @param array the array to iterate over
-+     * @param start the index to start iterating at
-+     * @param end   the index (exclusive) to finish iterating at
-+     * @throws IndexOutOfBoundsException if the start or end index is out of bounds
-+     * @throws IllegalArgumentException  if end index is before the start
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     */
-+    public ObjectArrayIterator(E[] array, int start, int end) {
-+        super();
-+        if (start < 0) {
-+            throw new ArrayIndexOutOfBoundsException("Start index must not be less than zero");
-+        }
-+        if (end > array.length) {
-+            throw new ArrayIndexOutOfBoundsException("End index must not be greater than the array length");
-+        }
-+        if (start > array.length) {
-+            throw new ArrayIndexOutOfBoundsException("Start index must not be greater than the array length");
-+        }
-+        if (end < start) {
-+            throw new IllegalArgumentException("End index must not be less than start index");
-+        }
-+        this.array = array;
-+        this.startIndex = start;
-+        this.endIndex = end;
-+        this.index = start;
-+    }
-+
-+    // Iterator interface
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Returns true if there are more elements to return from the array.
-+     *
-+     * @return true if there is a next element to return
-+     */
-+    public boolean hasNext() {
-+        return (this.index < this.endIndex);
-+    }
-+
-+    /**
-+     * Returns the next element in the array.
-+     *
-+     * @return the next element in the array
-+     * @throws NoSuchElementException if all the elements in the array
-+     *                                have already been returned
-+     */
-+    public E next() {
-+        if (hasNext() == false) {
-+            throw new NoSuchElementException();
-+        }
-+        return this.array[this.index++];
-+    }
-+
-+    /**
-+     * Throws {@link UnsupportedOperationException}.
-+     *
-+     * @throws UnsupportedOperationException always
-+     */
-+    public void remove() {
-+        throw new UnsupportedOperationException("remove() method is not supported for an ObjectArrayIterator");
-+    }
-+
-+    // Properties
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Gets the array that this iterator is iterating over.
-+     *
-+     * @return the array this iterator iterates over, or <code>null</code> if
-+     *         the no-arg constructor was used and {@link #setArray} has never
-+     *         been called with a valid array.
-+     */
-+    public E[] getArray() {
-+        return this.array;
-+    }
-+
-+    /**
-+     * Sets the array that the ArrayIterator should iterate over.
-+     * <p/>
-+     * This method may only be called once, otherwise an IllegalStateException
-+     * will occur.
-+     * <p/>
-+     * The {@link #reset} method can be used to reset the iterator if required.
-+     *
-+     * @param array the array that the iterator should iterate over
-+     * @throws IllegalStateException if the <code>array</code> was set in the constructor
-+     * @throws NullPointerException  if <code>array</code> is <code>null</code>
-+     */
-+    public void setArray(E[] array) {
-+        if (this.array != null) {
-+            throw new IllegalStateException("The array to iterate over has already been set");
-+        }
-+        this.array = array;
-+        this.startIndex = 0;
-+        this.endIndex = array.length;
-+        this.index = 0;
-+    }
-+
-+    /**
-+     * Gets the start index to loop from.
-+     *
-+     * @return the start index
-+     */
-+    public int getStartIndex() {
-+        return this.startIndex;
-+    }
-+
-+    /**
-+     * Gets the end index to loop to.
-+     *
-+     * @return the end index
-+     */
-+    public int getEndIndex() {
-+        return this.endIndex;
-+    }
-+
-+    /**
-+     * Resets the iterator back to the start index.
-+     */
-+    public void reset() {
-+        this.index = this.startIndex;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/ObjectArrayListIterator.java
-@@ -0,0 +1,203 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableListIterator;
-+
-+import java.util.ListIterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * Implements a {@link ListIterator} over an array of objects.
-+ * <p/>
-+ * This iterator does not support {@link #add} or {@link #remove}, as the object array
-+ * cannot be structurally modified. The {@link #set} method is supported however.
-+ * <p/>
-+ * The iterator implements a {@link #reset} method, allowing the reset of the iterator
-+ * back to the start if required.
-+ *
-+ * @author Neil O'Toole
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Phil Steitz
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @see org.apache.commons.collections15.iterators.ObjectArrayIterator
-+ * @see java.util.Iterator
-+ * @see java.util.ListIterator
-+ * @since Commons Collections 3.0
-+ */
-+public class ObjectArrayListIterator <E> extends ObjectArrayIterator<E> implements ListIterator<E>, ResettableListIterator<E> {
-+
-+    /**
-+     * Holds the index of the last item returned by a call to <code>next()</code>
-+     * or <code>previous()</code>. This is set to <code>-1</code> if neither method
-+     * has yet been invoked. <code>lastItemIndex</code> is used to to implement the
-+     * {@link #set} method.
-+     */
-+    protected int lastItemIndex = -1;
-+
-+    /**
-+     * Constructor for use with <code>setArray</code>.
-+     * <p/>
-+     * Using this constructor, the iterator is equivalent to an empty iterator
-+     * until {@link #setArray} is  called to establish the array to iterate over.
-+     */
-+    public ObjectArrayListIterator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs an ObjectArrayListIterator that will iterate over the values in the
-+     * specified array.
-+     *
-+     * @param array the array to iterate over
-+     * @throws NullPointerException if <code>array</code> is <code>null</code>
-+     */
-+    public ObjectArrayListIterator(E[] array) {
-+        super(array);
-+    }
-+
-+    /**
-+     * Constructs an ObjectArrayListIterator that will iterate over the values in the
-+     * specified array from a specific start index.
-+     *
-+     * @param array the array to iterate over
-+     * @param start the index to start iterating at
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     * @throws IndexOutOfBoundsException if the start index is out of bounds
-+     */
-+    public ObjectArrayListIterator(E[] array, int start) {
-+        super(array, start);
-+    }
-+
-+    /**
-+     * Construct an ObjectArrayListIterator that will iterate over a range of values
-+     * in the specified array.
-+     *
-+     * @param array the array to iterate over
-+     * @param start the index to start iterating at
-+     * @param end   the index (exclusive) to finish iterating at
-+     * @throws IndexOutOfBoundsException if the start or end index is out of bounds
-+     * @throws IllegalArgumentException  if end index is before the start
-+     * @throws NullPointerException      if <code>array</code> is <code>null</code>
-+     */
-+    public ObjectArrayListIterator(E[] array, int start, int end) {
-+        super(array, start, end);
-+    }
-+
-+    // ListIterator interface
-+    //-------------------------------------------------------------------------
-+
-+    /**
-+     * Returns true if there are previous elements to return from the array.
-+     *
-+     * @return true if there is a previous element to return
-+     */
-+    public boolean hasPrevious() {
-+        return (this.index > this.startIndex);
-+    }
-+
-+    /**
-+     * Gets the previous element from the array.
-+     *
-+     * @return the previous element
-+     * @throws NoSuchElementException if there is no previous element
-+     */
-+    public E previous() {
-+        if (hasPrevious() == false) {
-+            throw new NoSuchElementException();
-+        }
-+        this.lastItemIndex = --this.index;
-+        return this.array[this.index];
-+    }
-+
-+    /**
-+     * Gets the next element from the array.
-+     *
-+     * @return the next element
-+     * @throws NoSuchElementException if there is no next element
-+     */
-+    public E next() {
-+        if (hasNext() == false) {
-+            throw new NoSuchElementException();
-+        }
-+        this.lastItemIndex = this.index;
-+        return this.array[this.index++];
-+    }
-+
-+    /**
-+     * Gets the next index to be retrieved.
-+     *
-+     * @return the index of the item to be retrieved next
-+     */
-+    public int nextIndex() {
-+        return this.index - this.startIndex;
-+    }
-+
-+    /**
-+     * Gets the index of the item to be retrieved if {@link #previous()} is called.
-+     *
-+     * @return the index of the item to be retrieved next
-+     */
-+    public int previousIndex() {
-+        return this.index - this.startIndex - 1;
-+    }
-+
-+    /**
-+     * This iterator does not support modification of its backing array's size, and so will
-+     * always throw an {@link UnsupportedOperationException} when this method is invoked.
-+     *
-+     * @param obj the object to add
-+     * @throws UnsupportedOperationException always thrown.
-+     */
-+    public void add(E obj) {
-+        throw new UnsupportedOperationException("add() method is not supported");
-+    }
-+
-+    /**
-+     * Sets the element under the cursor.
-+     * <p/>
-+     * This method sets the element that was returned by the last call
-+     * to {@link #next()} of {@link #previous()}.
-+     * <p/>
-+     * <b>Note:</b> {@link ListIterator} implementations that support <code>add()</code>
-+     * and <code>remove()</code> only allow <code>set()</code> to be called once per call
-+     * to <code>next()</code> or <code>previous</code> (see the {@link ListIterator}
-+     * javadoc for more details). Since this implementation does not support
-+     * <code>add()</code> or <code>remove()</code>, <code>set()</code> may be
-+     * called as often as desired.
-+     *
-+     * @param obj the object to set into the array
-+     * @throws IllegalStateException if next() has not yet been called.
-+     * @throws ClassCastException    if the object type is unsuitable for the array
-+     */
-+    public void set(E obj) {
-+        if (this.lastItemIndex == -1) {
-+            throw new IllegalStateException("must call next() or previous() before a call to set()");
-+        }
-+
-+        this.array[this.lastItemIndex] = obj;
-+    }
-+
-+    /**
-+     * Resets the iterator back to the start index.
-+     */
-+    public void reset() {
-+        super.reset();
-+        this.lastItemIndex = -1;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/ObjectGraphIterator.java
-@@ -0,0 +1,268 @@
-+// GenericsNote: Won't be converted, not type safe.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ArrayStack;
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.Iterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * An Iterator that can traverse multiple iterators down an object graph.
-+ * <p/>
-+ * This iterator can extract multiple objects from a complex tree-like object graph.
-+ * The iteration starts from a single root object.
-+ * It uses a <code>Transformer</code> to extract the iterators and elements.
-+ * Its main benefit is that no intermediate <code>List</code> is created.
-+ * <p/>
-+ * For example, consider an object graph:
-+ * <pre>
-+ *                 |- Branch -- Leaf
-+ *                 |         \- Leaf
-+ *         |- Tree |         /- Leaf
-+ *         |       |- Branch -- Leaf
-+ *  Forest |                 \- Leaf
-+ *         |       |- Branch -- Leaf
-+ *         |       |         \- Leaf
-+ *         |- Tree |         /- Leaf
-+ *                 |- Branch -- Leaf
-+ *                 |- Branch -- Leaf</pre>
-+ * The following <code>Transformer</code>, used in this class, will extract all
-+ * the Leaf objects without creating a combined intermediate list:
-+ * <pre>
-+ * public Object transform(Object input) {
-+ *   if (input instanceof Forest) {
-+ *     return ((Forest) input).treeIterator();
-+ *   }
-+ *   if (input instanceof Tree) {
-+ *     return ((Tree) input).branchIterator();
-+ *   }
-+ *   if (input instanceof Branch) {
-+ *     return ((Branch) input).leafIterator();
-+ *   }
-+ *   if (input instanceof Leaf) {
-+ *     return input;
-+ *   }
-+ *   throw new ClassCastException();
-+ * }</pre>
-+ * <p/>
-+ * Internally, iteration starts from the root object. When next is called,
-+ * the transformer is called to examine the object. The transformer will return
-+ * either an iterator or an object. If the object is an Iterator, the next element
-+ * from that iterator is obtained and the process repeats. If the element is an object
-+ * it is returned.
-+ * <p/>
-+ * Under many circumstances, linking Iterators together in this manner is
-+ * more efficient (and convenient) than using nested for loops to extract a list.
-+ * <p/>
-+ * Note: this class is not type-safe in Java 1.5 (no generics).
-+ * <p/>
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.1
-+ */
-+public class ObjectGraphIterator implements Iterator {
-+
-+    /**
-+     * The stack of iterators
-+     */
-+    protected final ArrayStack stack = new ArrayStack(8);
-+    /**
-+     * The root object in the tree
-+     */
-+    protected Object root;
-+    /**
-+     * The transformer to use
-+     */
-+    protected Transformer transformer;
-+
-+    /**
-+     * Whether there is another element in the iteration
-+     */
-+    protected boolean hasNext = false;
-+    /**
-+     * The current iterator
-+     */
-+    protected Iterator currentIterator;
-+    /**
-+     * The current value
-+     */
-+    protected Object currentValue;
-+    /**
-+     * The last used iterator, needed for remove()
-+     */
-+    protected Iterator lastUsedIterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs an ObjectGraphIterator using a root object and transformer.
-+     * <p/>
-+     * The root object can be an iterator, in which case it will be immediately
-+     * looped around.
-+     *
-+     * @param root        the root object, null will result in an empty iterator
-+     * @param transformer the transformer to use, null will use a no effect transformer
-+     */
-+    public ObjectGraphIterator(Object root, Transformer transformer) {
-+        super();
-+        if (root instanceof Iterator) {
-+            this.currentIterator = (Iterator) root;
-+        } else {
-+            this.root = root;
-+        }
-+        this.transformer = transformer;
-+    }
-+
-+    /**
-+     * Constructs a ObjectGraphIterator that will handle an iterator of iterators.
-+     * <p/>
-+     * This constructor exists for convenience to emphasise that this class can
-+     * be used to iterate over nested iterators. That is to say that the iterator
-+     * passed in here contains other iterators, which may in turn contain further
-+     * iterators.
-+     *
-+     * @param rootIterator the root iterator, null will result in an empty iterator
-+     */
-+    public ObjectGraphIterator(Iterator rootIterator) {
-+        super();
-+        this.currentIterator = rootIterator;
-+        this.transformer = null;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Loops around the iterators to find the next value to return.
-+     */
-+    protected void updateCurrentIterator() {
-+        if (hasNext) {
-+            return;
-+        }
-+        if (currentIterator == null) {
-+            if (root == null) {
-+                // do nothing, hasNext will be false
-+            } else {
-+                if (transformer == null) {
-+                    findNext(root);
-+                } else {
-+                    findNext(transformer.transform(root));
-+                }
-+                root = null;
-+            }
-+        } else {
-+            findNextByIterator(currentIterator);
-+        }
-+    }
-+
-+    /**
-+     * Finds the next object in the iteration given any start object.
-+     *
-+     * @param value the value to start from
-+     */
-+    protected void findNext(Object value) {
-+        if (value instanceof Iterator) {
-+            // need to examine this iterator
-+            findNextByIterator((Iterator) value);
-+        } else {
-+            // next value found
-+            currentValue = value;
-+            hasNext = true;
-+        }
-+    }
-+
-+    /**
-+     * Finds the next object in the iteration given an iterator.
-+     *
-+     * @param iterator the iterator to start from
-+     */
-+    protected void findNextByIterator(Iterator iterator) {
-+        if (iterator != currentIterator) {
-+            // recurse a level
-+            if (currentIterator != null) {
-+                stack.push(currentIterator);
-+            }
-+            currentIterator = iterator;
-+        }
-+
-+        while (currentIterator.hasNext() && hasNext == false) {
-+            Object next = currentIterator.next();
-+            if (transformer != null) {
-+                next = transformer.transform(next);
-+            }
-+            findNext(next);
-+        }
-+        if (hasNext) {
-+            // next value found
-+        } else if (stack.isEmpty()) {
-+            // all iterators exhausted
-+        } else {
-+            // current iterator exhausted, go up a level
-+            currentIterator = (Iterator) stack.pop();
-+            findNextByIterator(currentIterator);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks whether there are any more elements in the iteration to obtain.
-+     *
-+     * @return true if elements remain in the iteration
-+     */
-+    public boolean hasNext() {
-+        updateCurrentIterator();
-+        return hasNext;
-+    }
-+
-+    /**
-+     * Gets the next element of the iteration.
-+     *
-+     * @return the next element from the iteration
-+     * @throws NoSuchElementException if all the Iterators are exhausted
-+     */
-+    public Object next() {
-+        updateCurrentIterator();
-+        if (hasNext == false) {
-+            throw new NoSuchElementException("No more elements in the iteration");
-+        }
-+        lastUsedIterator = currentIterator;
-+        Object result = currentValue;
-+        currentValue = null;
-+        hasNext = false;
-+        return result;
-+    }
-+
-+    /**
-+     * Removes from the underlying collection the last element returned.
-+     * <p/>
-+     * This method calls remove() on the underlying Iterator and it may
-+     * throw an UnsupportedOperationException if the underlying Iterator
-+     * does not support this method.
-+     *
-+     * @throws UnsupportedOperationException if the remove operator is not supported by the underlying Iterator
-+     * @throws IllegalStateException         if the next method has not yet been called, or the remove method has
-+     *                                       already been called after the last call to the next method.
-+     */
-+    public void remove() {
-+        if (lastUsedIterator == null) {
-+            throw new IllegalStateException("Iterator remove() cannot be called at this time");
-+        }
-+        lastUsedIterator.remove();
-+        lastUsedIterator = null;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/SingletonIterator.java
-@@ -0,0 +1,135 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableIterator;
-+
-+import java.util.Iterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * <code>SingletonIterator</code> is an {@link Iterator} over a single
-+ * object instance.
-+ *
-+ * @author James Strachan
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Rodney Waldhoff
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.0
-+ */
-+public class SingletonIterator <E> implements Iterator<E>, ResettableIterator<E> {
-+
-+    /**
-+     * Whether remove is allowed
-+     */
-+    private final boolean removeAllowed;
-+    /**
-+     * Is the cursor before the first element
-+     */
-+    private boolean beforeFirst = true;
-+    /**
-+     * Has the element been removed
-+     */
-+    private boolean removed = false;
-+    /**
-+     * The object
-+     */
-+    private E object;
-+
-+    /**
-+     * Constructs a new <code>SingletonIterator</code> where <code>remove</code>
-+     * is a permitted operation.
-+     *
-+     * @param object the single object to return from the iterator
-+     */
-+    public SingletonIterator(E object) {
-+        this(object, true);
-+    }
-+
-+    /**
-+     * Constructs a new <code>SingletonIterator</code> optionally choosing if
-+     * <code>remove</code> is a permitted operation.
-+     *
-+     * @param object        the single object to return from the iterator
-+     * @param removeAllowed true if remove is allowed
-+     * @since Commons Collections 3.1
-+     */
-+    public SingletonIterator(E object, boolean removeAllowed) {
-+        super();
-+        this.object = object;
-+        this.removeAllowed = removeAllowed;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Is another object available from the iterator?
-+     * <p/>
-+     * This returns true if the single object hasn't been returned yet.
-+     *
-+     * @return true if the single object hasn't been returned yet
-+     */
-+    public boolean hasNext() {
-+        return (beforeFirst && !removed);
-+    }
-+
-+    /**
-+     * Get the next object from the iterator.
-+     * <p/>
-+     * This returns the single object if it hasn't been returned yet.
-+     *
-+     * @return the single object
-+     * @throws NoSuchElementException if the single object has already
-+     *                                been returned
-+     */
-+    public E next() {
-+        if (!beforeFirst || removed) {
-+            throw new NoSuchElementException();
-+        }
-+        beforeFirst = false;
-+        return object;
-+    }
-+
-+    /**
-+     * Remove the object from this iterator.
-+     *
-+     * @throws IllegalStateException         if the <tt>next</tt> method has not
-+     *                                       yet been called, or the <tt>remove</tt> method has already
-+     *                                       been called after the last call to the <tt>next</tt>
-+     *                                       method.
-+     * @throws UnsupportedOperationException if remove is not supported
-+     */
-+    public void remove() {
-+        if (removeAllowed) {
-+            if (removed || beforeFirst) {
-+                throw new IllegalStateException();
-+            } else {
-+                object = null;
-+                removed = true;
-+            }
-+        } else {
-+            throw new UnsupportedOperationException();
-+        }
-+    }
-+
-+    /**
-+     * Reset the iterator to the start.
-+     */
-+    public void reset() {
-+        beforeFirst = true;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/SingletonListIterator.java
-@@ -0,0 +1,176 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.ResettableListIterator;
-+
-+import java.util.ListIterator;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * <code>SingletonIterator</code> is an {@link ListIterator} over a single
-+ * object instance.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Rodney Waldhoff
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.1
-+ */
-+public class SingletonListIterator <E> implements ListIterator<E>, ResettableListIterator<E> {
-+
-+    private boolean beforeFirst = true;
-+    private boolean nextCalled = false;
-+    private boolean removed = false;
-+    private E object;
-+
-+    /**
-+     * Constructs a new <code>SingletonListIterator</code>.
-+     *
-+     * @param object the single object to return from the iterator
-+     */
-+    public SingletonListIterator(E object) {
-+        super();
-+        this.object = object;
-+    }
-+
-+    /**
-+     * Is another object available from the iterator?
-+     * <p/>
-+     * This returns true if the single object hasn't been returned yet.
-+     *
-+     * @return true if the single object hasn't been returned yet
-+     */
-+    public boolean hasNext() {
-+        return beforeFirst && !removed;
-+    }
-+
-+    /**
-+     * Is a previous object available from the iterator?
-+     * <p/>
-+     * This returns true if the single object has been returned.
-+     *
-+     * @return true if the single object has been returned
-+     */
-+    public boolean hasPrevious() {
-+        return !beforeFirst && !removed;
-+    }
-+
-+    /**
-+     * Returns the index of the element that would be returned by a subsequent
-+     * call to <tt>next</tt>.
-+     *
-+     * @return 0 or 1 depending on current state.
-+     */
-+    public int nextIndex() {
-+        return (beforeFirst ? 0 : 1);
-+    }
-+
-+    /**
-+     * Returns the index of the element that would be returned by a subsequent
-+     * call to <tt>previous</tt>. A return value of -1 indicates that the iterator is currently at
-+     * the start.
-+     *
-+     * @return 0 or -1 depending on current state.
-+     */
-+    public int previousIndex() {
-+        return (beforeFirst ? -1 : 0);
-+    }
-+
-+    /**
-+     * Get the next object from the iterator.
-+     * <p/>
-+     * This returns the single object if it hasn't been returned yet.
-+     *
-+     * @return the single object
-+     * @throws NoSuchElementException if the single object has already
-+     *                                been returned
-+     */
-+    public E next() {
-+        if (!beforeFirst || removed) {
-+            throw new NoSuchElementException();
-+        }
-+        beforeFirst = false;
-+        nextCalled = true;
-+        return object;
-+    }
-+
-+    /**
-+     * Get the previous object from the iterator.
-+     * <p/>
-+     * This returns the single object if it has been returned.
-+     *
-+     * @return the single object
-+     * @throws NoSuchElementException if the single object has not already
-+     *                                been returned
-+     */
-+    public E previous() {
-+        if (beforeFirst || removed) {
-+            throw new NoSuchElementException();
-+        }
-+        beforeFirst = true;
-+        return object;
-+    }
-+
-+    /**
-+     * Remove the object from this iterator.
-+     *
-+     * @throws IllegalStateException if the <tt>next</tt> or <tt>previous</tt>
-+     *                               method has not yet been called, or the <tt>remove</tt> method
-+     *                               has already been called after the last call to <tt>next</tt>
-+     *                               or <tt>previous</tt>.
-+     */
-+    public void remove() {
-+        if (!nextCalled || removed) {
-+            throw new IllegalStateException();
-+        } else {
-+            object = null;
-+            removed = true;
-+        }
-+    }
-+
-+    /**
-+     * Add always throws {@link UnsupportedOperationException}.
-+     *
-+     * @throws UnsupportedOperationException always
-+     */
-+    public void add(E obj) {
-+        throw new UnsupportedOperationException("add() is not supported by this iterator");
-+    }
-+
-+    /**
-+     * Set sets the value of the singleton.
-+     *
-+     * @param obj the object to set
-+     * @throws IllegalStateException if <tt>next</tt> has not been called
-+     *                               or the object has been removed
-+     */
-+    public void set(E obj) {
-+        if (!nextCalled || removed) {
-+            throw new IllegalStateException();
-+        }
-+        this.object = obj;
-+    }
-+
-+    /**
-+     * Reset the iterator back to the start.
-+     */
-+    public void reset() {
-+        beforeFirst = true;
-+        nextCalled = false;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/TransformIterator.java
-@@ -0,0 +1,155 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates an iterator such that each element returned is transformed.
-+ *
-+ * @author James Strachan
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 1.0
-+ */
-+public class TransformIterator <I,O> implements Iterator<O> {
-+
-+    /**
-+     * The iterator being used
-+     */
-+    private Iterator<I> iterator;
-+    /**
-+     * The transformer being used
-+     */
-+    private Transformer<I, O> transformer;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new <code>TransformIterator</code> that will not function
-+     * until the {@link #setIterator(Iterator) setIterator} method is
-+     * invoked.
-+     */
-+    public TransformIterator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new <code>TransformIterator</code> that won't transform
-+     * elements from the given iterator.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public TransformIterator(Iterator<I> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    /**
-+     * Constructs a new <code>TransformIterator</code> that will use the
-+     * given iterator and transformer.  If the given transformer is null,
-+     * then objects will not be transformed.
-+     *
-+     * @param iterator    the iterator to use
-+     * @param transformer the transformer to use
-+     */
-+    public TransformIterator(Iterator<I> iterator, Transformer<I, O> transformer) {
-+        super();
-+        this.iterator = iterator;
-+        this.transformer = transformer;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    /**
-+     * Gets the next object from the iteration, transforming it using the
-+     * current transformer. If the transformer is null, no transformation
-+     * occurs and the object from the iterator is returned directly.
-+     *
-+     * @return the next object
-+     * @throws java.util.NoSuchElementException
-+     *          if there are no more elements
-+     */
-+    public O next() {
-+        return transform(iterator.next());
-+    }
-+
-+    public void remove() {
-+        iterator.remove();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the iterator this iterator is using.
-+     *
-+     * @return the iterator.
-+     */
-+    public Iterator<I> getIterator() {
-+        return iterator;
-+    }
-+
-+    /**
-+     * Sets the iterator for this iterator to use.
-+     * If iteration has started, this effectively resets the iterator.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public void setIterator(Iterator<I> iterator) {
-+        this.iterator = iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the transformer this iterator is using.
-+     *
-+     * @return the transformer.
-+     */
-+    public Transformer<I, O> getTransformer() {
-+        return transformer;
-+    }
-+
-+    /**
-+     * Sets the transformer this the iterator to use.
-+     * A null transformer is a no-op transformer.
-+     *
-+     * @param transformer the transformer to use
-+     */
-+    public void setTransformer(Transformer<I, O> transformer) {
-+        this.transformer = transformer;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Transforms the given object using the transformer.
-+     * If the transformer is null, the original object is returned as-is.
-+     *
-+     * @param source the object to transform
-+     * @return the transformed object
-+     */
-+    protected O transform(I source) {
-+        if (transformer != null) {
-+            return transformer.transform(source);
-+        }
-+        // Generics hack
-+        Object sourceObj = source;
-+        return (O) sourceObj;
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/UniqueFilterIterator.java
-@@ -0,0 +1,45 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.functors.UniquePredicate;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * A FilterIterator which only returns "unique" Objects.  Internally,
-+ * the Iterator maintains a Set of objects it has already encountered,
-+ * and duplicate Objects are skipped.
-+ *
-+ * @author Matt Hall, John Watkinson, Morgan Delagrange
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 2.1
-+ */
-+public class UniqueFilterIterator <E> extends FilterIterator<E> {
-+
-+    //-------------------------------------------------------------------------
-+    
-+    /**
-+     * Constructs a new <code>UniqueFilterIterator</code>.
-+     *
-+     * @param iterator the iterator to use
-+     */
-+    public UniqueFilterIterator(Iterator<E> iterator) {
-+        super(iterator, UniquePredicate.getInstance());
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/UnmodifiableIterator.java
-@@ -0,0 +1,80 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+
-+import java.util.Iterator;
-+
-+/**
-+ * Decorates an iterator such that it cannot be modified.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableIterator <E> implements Iterator<E>, Unmodifiable {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    private Iterator<E> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Decorates the specified iterator such that it cannot be modified.
-+     * <p/>
-+     * If the iterator is already unmodifiable it is returned directly.
-+     *
-+     * @param iterator the iterator to decorate
-+     * @throws IllegalArgumentException if the iterator is null
-+     */
-+    public static <E> Iterator<E> decorate(Iterator<E> iterator) {
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("Iterator must not be null");
-+        }
-+        if (iterator instanceof Unmodifiable) {
-+            return iterator;
-+        }
-+        return new UnmodifiableIterator<E>(iterator);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor.
-+     *
-+     * @param iterator the iterator to decorate
-+     */
-+    private UnmodifiableIterator(Iterator<E> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public E next() {
-+        return iterator.next();
-+    }
-+
-+    public void remove() {
-+        throw new UnsupportedOperationException("remove() is not supported");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/UnmodifiableListIterator.java
-@@ -0,0 +1,102 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+
-+import java.util.ListIterator;
-+
-+/**
-+ * Decorates a list iterator such that it cannot be modified.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableListIterator <E> implements ListIterator<E>, Unmodifiable {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    private ListIterator<E> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Decorates the specified iterator such that it cannot be modified.
-+     *
-+     * @param iterator the iterator to decorate
-+     * @throws IllegalArgumentException if the iterator is null
-+     */
-+    public static <E> ListIterator<E> decorate(ListIterator<E> iterator) {
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("ListIterator must not be null");
-+        }
-+        if (iterator instanceof Unmodifiable) {
-+            return iterator;
-+        }
-+        return new UnmodifiableListIterator<E>(iterator);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor.
-+     *
-+     * @param iterator the iterator to decorate
-+     */
-+    private UnmodifiableListIterator(ListIterator<E> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public E next() {
-+        return iterator.next();
-+    }
-+
-+    public int nextIndex() {
-+        return iterator.nextIndex();
-+    }
-+
-+    public boolean hasPrevious() {
-+        return iterator.hasPrevious();
-+    }
-+
-+    public E previous() {
-+        return iterator.previous();
-+    }
-+
-+    public int previousIndex() {
-+        return iterator.previousIndex();
-+    }
-+
-+    public void remove() {
-+        throw new UnsupportedOperationException("remove() is not supported");
-+    }
-+
-+    public void set(E obj) {
-+        throw new UnsupportedOperationException("set() is not supported");
-+    }
-+
-+    public void add(E obj) {
-+        throw new UnsupportedOperationException("add() is not supported");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/UnmodifiableMapIterator.java
-@@ -0,0 +1,89 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.Unmodifiable;
-+
-+/**
-+ * Decorates a map iterator such that it cannot be modified.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableMapIterator <K,V> implements MapIterator<K, V>, Unmodifiable {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    private MapIterator<K, V> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Decorates the specified iterator such that it cannot be modified.
-+     *
-+     * @param iterator the iterator to decorate
-+     * @throws IllegalArgumentException if the iterator is null
-+     */
-+    public static <K,V> MapIterator<K, V> decorate(MapIterator<K, V> iterator) {
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("MapIterator must not be null");
-+        }
-+        if (iterator instanceof Unmodifiable) {
-+            return iterator;
-+        }
-+        return new UnmodifiableMapIterator<K, V>(iterator);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor.
-+     *
-+     * @param iterator the iterator to decorate
-+     */
-+    private UnmodifiableMapIterator(MapIterator<K, V> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public K next() {
-+        return iterator.next();
-+    }
-+
-+    public K getKey() {
-+        return iterator.getKey();
-+    }
-+
-+    public V getValue() {
-+        return iterator.getValue();
-+    }
-+
-+    public V setValue(V value) {
-+        throw new UnsupportedOperationException("setValue() is not supported");
-+    }
-+
-+    public void remove() {
-+        throw new UnsupportedOperationException("remove() is not supported");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/UnmodifiableOrderedMapIterator.java
-@@ -0,0 +1,97 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 1999-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.iterators;
-+
-+import org.apache.commons.collections15.OrderedMapIterator;
-+import org.apache.commons.collections15.Unmodifiable;
-+
-+/**
-+ * Decorates an ordered map iterator such that it cannot be modified.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:24 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableOrderedMapIterator <K,V> implements OrderedMapIterator<K, V>, Unmodifiable {
-+
-+    /**
-+     * The iterator being decorated
-+     */
-+    private OrderedMapIterator<K, V> iterator;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Decorates the specified iterator such that it cannot be modified.
-+     *
-+     * @param iterator the iterator to decorate
-+     * @throws IllegalArgumentException if the iterator is null
-+     */
-+    public static <K,V> OrderedMapIterator<K, V> decorate(OrderedMapIterator<K, V> iterator) {
-+        if (iterator == null) {
-+            throw new IllegalArgumentException("OrderedMapIterator must not be null");
-+        }
-+        if (iterator instanceof Unmodifiable) {
-+            return iterator;
-+        }
-+        return new UnmodifiableOrderedMapIterator<K, V>(iterator);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor.
-+     *
-+     * @param iterator the iterator to decorate
-+     */
-+    private UnmodifiableOrderedMapIterator(OrderedMapIterator<K, V> iterator) {
-+        super();
-+        this.iterator = iterator;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean hasNext() {
-+        return iterator.hasNext();
-+    }
-+
-+    public K next() {
-+        return iterator.next();
-+    }
-+
-+    public boolean hasPrevious() {
-+        return iterator.hasPrevious();
-+    }
-+
-+    public K previous() {
-+        return iterator.previous();
-+    }
-+
-+    public K getKey() {
-+        return iterator.getKey();
-+    }
-+
-+    public V getValue() {
-+        return iterator.getValue();
-+    }
-+
-+    public V setValue(V value) {
-+        throw new UnsupportedOperationException("setValue() is not supported");
-+    }
-+
-+    public void remove() {
-+        throw new UnsupportedOperationException("remove() is not supported");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/iterators/package.html
-@@ -0,0 +1,26 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:24 pents90 Exp $ -->
-+ <!--
-+   Copyright 2002-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<body>
-+<p>
-+This package contains implementations of the
-+{@link java.util.Iterator Iterator} interface.
-+<p>
-+You may also consider using 
-+{@link org.apache.commons.collections.IteratorUtils IteratorUtils},
-+which is a single class that uses static methods to construct instances
-+of the classes in this package.
-+</body>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/AbstractKeyValue.java
-@@ -0,0 +1,81 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import org.apache.commons.collections15.KeyValue;
-+
-+/**
-+ * Abstract pair class to assist with creating KeyValue and MapEntry implementations.
-+ *
-+ * @author James Strachan
-+ * @author Michael A. Smith
-+ * @author Neil O'Toole
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractKeyValue <K,V> implements KeyValue<K, V> {
-+
-+    /**
-+     * The key
-+     */
-+    protected K key;
-+    /**
-+     * The value
-+     */
-+    protected V value;
-+
-+    /**
-+     * Constructs a new pair with the specified key and given value.
-+     *
-+     * @param key   the key for the entry, may be null
-+     * @param value the value for the entry, may be null
-+     */
-+    protected AbstractKeyValue(K key, V value) {
-+        super();
-+        this.key = key;
-+        this.value = value;
-+    }
-+
-+    /**
-+     * Gets the key from the pair.
-+     *
-+     * @return the key
-+     */
-+    public K getKey() {
-+        return key;
-+    }
-+
-+    /**
-+     * Gets the value from the pair.
-+     *
-+     * @return the value
-+     */
-+    public V getValue() {
-+        return value;
-+    }
-+
-+    /**
-+     * Gets a debugging String view of the pair.
-+     *
-+     * @return a String view of the entry
-+     */
-+    public String toString() {
-+        return new StringBuffer().append(getKey()).append('=').append(getValue()).toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/AbstractMapEntry.java
-@@ -0,0 +1,89 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import java.util.Map;
-+
-+/**
-+ * Abstract Pair class to assist with creating correct Map Entry implementations.
-+ *
-+ * @author James Strachan
-+ * @author Michael A. Smith
-+ * @author Neil O'Toole
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractMapEntry <K,V> extends AbstractKeyValue<K, V> implements Map.Entry<K, V> {
-+
-+    /**
-+     * Constructs a new entry with the given key and given value.
-+     *
-+     * @param key   the key for the entry, may be null
-+     * @param value the value for the entry, may be null
-+     */
-+    protected AbstractMapEntry(K key, V value) {
-+        super(key, value);
-+    }
-+
-+    // Map.Entry interface
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Sets the value stored in this Map Entry.
-+     * <p/>
-+     * This Map Entry is not connected to a Map, so only the local data is changed.
-+     *
-+     * @param value the new value
-+     * @return the previous value
-+     */
-+    public V setValue(V value) {
-+        V answer = this.value;
-+        this.value = value;
-+        return answer;
-+    }
-+
-+    /**
-+     * Compares this Map Entry with another Map Entry.
-+     * <p/>
-+     * Implemented per API documentation of {@link java.util.Map.Entry#equals(Object)}
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal key and value
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof Map.Entry == false) {
-+            return false;
-+        }
-+        Map.Entry other = (Map.Entry) obj;
-+        return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) && (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
-+    }
-+
-+    /**
-+     * Gets a hashCode compatible with the equals method.
-+     * <p/>
-+     * Implemented per API documentation of {@link java.util.Map.Entry#hashCode()}
-+     *
-+     * @return a suitable hash code
-+     */
-+    public int hashCode() {
-+        return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode());
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/AbstractMapEntryDecorator.java
-@@ -0,0 +1,88 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import org.apache.commons.collections15.KeyValue;
-+
-+import java.util.Map;
-+
-+/**
-+ * Provides a base decorator that allows additional functionality to be added
-+ * to a Map Entry.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractMapEntryDecorator <K,V> implements Map.Entry<K, V>, KeyValue<K, V> {
-+
-+    /**
-+     * The <code>Map.Entry</code> to decorate
-+     */
-+    protected final Map.Entry<K, V> entry;
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param entry the <code>Map.Entry</code> to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractMapEntryDecorator(Map.Entry<K, V> entry) {
-+        if (entry == null) {
-+            throw new IllegalArgumentException("Map Entry must not be null");
-+        }
-+        this.entry = entry;
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected Map.Entry<K, V> getMapEntry() {
-+        return entry;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K getKey() {
-+        return entry.getKey();
-+    }
-+
-+    public V getValue() {
-+        return entry.getValue();
-+    }
-+
-+    public V setValue(V object) {
-+        return entry.setValue(object);
-+    }
-+
-+    public boolean equals(Object object) {
-+        if (object == this) {
-+            return true;
-+        }
-+        return entry.equals(object);
-+    }
-+
-+    public int hashCode() {
-+        return entry.hashCode();
-+    }
-+
-+    public String toString() {
-+        return entry.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/DefaultKeyValue.java
-@@ -0,0 +1,154 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import org.apache.commons.collections15.KeyValue;
-+
-+import java.util.Map;
-+
-+/**
-+ * A mutable KeyValue pair that does not implement MapEntry.
-+ * <p/>
-+ * Note that a <code>DefaultKeyValue</code> instance may not contain
-+ * itself as a key or value.
-+ *
-+ * @author James Strachan
-+ * @author Michael A. Smith
-+ * @author Neil O'Toole
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class DefaultKeyValue <K,V> extends AbstractKeyValue<K, V> {
-+
-+    /**
-+     * Constructs a new pair with a null key and null value.
-+     */
-+    public DefaultKeyValue() {
-+        super(null, null);
-+    }
-+
-+    /**
-+     * Constructs a new pair with the specified key and given value.
-+     *
-+     * @param key   the key for the entry, may be null
-+     * @param value the value for the entry, may be null
-+     */
-+    public DefaultKeyValue(final K key, final V value) {
-+        super(key, value);
-+    }
-+
-+    /**
-+     * Constructs a new pair from the specified KeyValue.
-+     *
-+     * @param pair the pair to copy, must not be null
-+     * @throws NullPointerException if the entry is null
-+     */
-+    public DefaultKeyValue(final KeyValue<K, V> pair) {
-+        super(pair.getKey(), pair.getValue());
-+    }
-+
-+    /**
-+     * Constructs a new pair from the specified MapEntry.
-+     *
-+     * @param entry the entry to copy, must not be null
-+     * @throws NullPointerException if the entry is null
-+     */
-+    public DefaultKeyValue(final Map.Entry<K, V> entry) {
-+        super(entry.getKey(), entry.getValue());
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Sets the key.
-+     *
-+     * @param key the new key
-+     * @return the old key
-+     * @throws IllegalArgumentException if key is this object
-+     */
-+    public K setKey(final K key) {
-+        if ((Object) key == this) {
-+            throw new IllegalArgumentException("DefaultKeyValue may not contain itself as a key.");
-+        }
-+
-+        final K old = this.key;
-+        this.key = key;
-+        return old;
-+    }
-+
-+    /**
-+     * Sets the value.
-+     *
-+     * @param value the new value
-+     * @return the old value of the value
-+     * @throws IllegalArgumentException if value is this object
-+     */
-+    public V setValue(final V value) {
-+        if ((Object) value == this) {
-+            throw new IllegalArgumentException("DefaultKeyValue may not contain itself as a value.");
-+        }
-+
-+        final V old = this.value;
-+        this.value = value;
-+        return old;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns a new <code>Map.Entry</code> object with key and value from this pair.
-+     *
-+     * @return a MapEntry instance
-+     */
-+    public Map.Entry<K, V> toMapEntry() {
-+        return new DefaultMapEntry<K, V>(this);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares this Map Entry with another Map Entry.
-+     * <p/>
-+     * Returns true if the compared object is also a <code>DefaultKeyValue</code>,
-+     * and its key and value are equal to this object's key and value.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal key and value
-+     */
-+    public boolean equals(final Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof DefaultKeyValue == false) {
-+            return false;
-+        }
-+
-+        DefaultKeyValue other = (DefaultKeyValue) obj;
-+        return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) && (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
-+    }
-+
-+    /**
-+     * Gets a hashCode compatible with the equals method.
-+     * <p/>
-+     * Implemented per API documentation of {@link java.util.Map.Entry#hashCode()},
-+     * however subclasses may override this.
-+     *
-+     * @return a suitable hash code
-+     */
-+    public int hashCode() {
-+        return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode());
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/DefaultMapEntry.java
-@@ -0,0 +1,66 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import org.apache.commons.collections15.KeyValue;
-+
-+import java.util.Map;
-+
-+/**
-+ * A restricted implementation of {@link java.util.Map.Entry} that prevents
-+ * the MapEntry contract from being broken.
-+ *
-+ * @author James Strachan
-+ * @author Michael A. Smith
-+ * @author Neil O'Toole
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class DefaultMapEntry <K,V> extends AbstractMapEntry<K, V> {
-+
-+    /**
-+     * Constructs a new entry with the specified key and given value.
-+     *
-+     * @param key   the key for the entry, may be null
-+     * @param value the value for the entry, may be null
-+     */
-+    public DefaultMapEntry(final K key, final V value) {
-+        super(key, value);
-+    }
-+
-+    /**
-+     * Constructs a new entry from the specified KeyValue.
-+     *
-+     * @param pair the pair to copy, must not be null
-+     * @throws NullPointerException if the entry is null
-+     */
-+    public DefaultMapEntry(final KeyValue<K, V> pair) {
-+        super(pair.getKey(), pair.getValue());
-+    }
-+
-+    /**
-+     * Constructs a new entry from the specified MapEntry.
-+     *
-+     * @param entry the entry to copy, must not be null
-+     * @throws NullPointerException if the entry is null
-+     */
-+    public DefaultMapEntry(final Map.Entry<K, V> entry) {
-+        super(entry.getKey(), entry.getValue());
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/MultiKey.java
-@@ -0,0 +1,202 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import java.io.Serializable;
-+import java.util.Arrays;
-+
-+/**
-+ * A <code>MultiKey</code> allows multiple map keys to be merged together.
-+ * <p/>
-+ * The purpose of this class is to avoid the need to write code to handle
-+ * maps of maps. An example might be the need to lookup a filename by
-+ * key and locale. The typical solution might be nested maps. This class
-+ * can be used instead by creating an instance passing in the key and locale.
-+ * <p/>
-+ * Example usage:
-+ * <pre>
-+ * // populate map with data mapping key+locale to localizedText
-+ * Map map = new HashMap();
-+ * MultiKey multiKey = new MultiKey(key, locale);
-+ * map.put(multiKey, localizedText);
-+ * <p/>
-+ * // later retireve the localized text
-+ * MultiKey multiKey = new MultiKey(key, locale);
-+ * String localizedText = (String) map.get(multiKey);
-+ * </pre>
-+ *
-+ * @author Howard Lewis Ship
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class MultiKey <K> implements Serializable {
-+    // This class could implement List, but that would confuse it's purpose
-+
-+    /**
-+     * Serialisation version
-+     */
-+    private static final long serialVersionUID = 4465448607415788805L;
-+
-+    /**
-+     * The individual keys
-+     */
-+    private final K[] keys;
-+    /**
-+     * The cached hashCode
-+     */
-+    private final int hashCode;
-+
-+    /**
-+     * Constructor taking two keys.
-+     * <p/>
-+     * The keys should be immutable
-+     * If they are not then they must not be changed after adding to the MultiKey.
-+     *
-+     * @param keys the keys
-+     */
-+    public MultiKey(K... keys) {
-+        this(keys, true);
-+    }
-+
-+    /**
-+     * Constructor taking an array of keys, optionally choosing whether to clone.
-+     * <p/>
-+     * <b>If the array is not cloned, then it must not be modified.</b>
-+     * <p/>
-+     * This method is public for performance reasons only, to avoid a clone.
-+     * The hashcode is calculated once here in this method.
-+     * Therefore, changing the array passed in would not change the hashcode but
-+     * would change the equals method, which is a bug.
-+     * <p/>
-+     * This is the only fully safe usage of this constructor, as the object array
-+     * is never made available in a variable:
-+     * <pre>
-+     * new MultiKey(new Object[] {...}, false);
-+     * </pre>
-+     * <p/>
-+     * The keys should be immutable
-+     * If they are not then they must not be changed after adding to the MultiKey.
-+     *
-+     * @param keys      the array of keys, not null
-+     * @param makeClone true to clone the array, false to assign it
-+     * @throws IllegalArgumentException if the key array is null
-+     * @since Commons Collections 3.1
-+     */
-+    public MultiKey(K[] keys, boolean makeClone) {
-+        super();
-+        if (keys == null) {
-+            throw new IllegalArgumentException("The array of keys must not be null");
-+        }
-+        if (makeClone) {
-+            this.keys = (K[]) keys.clone();
-+        } else {
-+            this.keys = keys;
-+        }
-+
-+        int total = 0;
-+        for (int i = 0; i < keys.length; i++) {
-+            if (keys[i] != null) {
-+                total ^= keys[i].hashCode();
-+            }
-+        }
-+        hashCode = total;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets a clone of the array of keys.
-+     * <p/>
-+     * The keys should be immutable
-+     * If they are not then they must not be changed.
-+     *
-+     * @return the individual keys
-+     */
-+    public K[] getKeys() {
-+        return keys.clone();
-+    }
-+
-+    /**
-+     * Gets the key at the specified index.
-+     * <p/>
-+     * The key should be immutable.
-+     * If it is not then it must not be changed.
-+     *
-+     * @param index the index to retrieve
-+     * @return the key at the index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     * @since Commons Collections 3.1
-+     */
-+    public K getKey(int index) {
-+        return keys[index];
-+    }
-+
-+    /**
-+     * Gets the size of the list of keys.
-+     *
-+     * @return the size of the list of keys
-+     * @since Commons Collections 3.1
-+     */
-+    public int size() {
-+        return keys.length;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares this object to another.
-+     * <p/>
-+     * To be equal, the other object must be a <code>MultiKey</code> with the
-+     * same number of keys which are also equal.
-+     *
-+     * @param other the other object to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object other) {
-+        if (other == this) {
-+            return true;
-+        }
-+        if (other instanceof MultiKey) {
-+            MultiKey otherMulti = (MultiKey) other;
-+            return Arrays.equals(keys, otherMulti.keys);
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Gets the combined hash code that is computed from all the keys.
-+     * <p/>
-+     * This value is computed once and then cached, so elements should not
-+     * change their hash codes once created (note that this is the same
-+     * constraint that would be used if the individual keys elements were
-+     * themselves {@link java.util.Map Map} keys.
-+     *
-+     * @return the hash code
-+     */
-+    public int hashCode() {
-+        return hashCode;
-+    }
-+
-+    /**
-+     * Gets a debugging string version of the key.
-+     *
-+     * @return a debugging string
-+     */
-+    public String toString() {
-+        return "MultiKey" + Arrays.asList(keys).toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/TiedMapEntry.java
-@@ -0,0 +1,138 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import org.apache.commons.collections15.KeyValue;
-+
-+import java.io.Serializable;
-+import java.util.Map;
-+
-+/**
-+ * A Map Entry tied to a map underneath.
-+ * <p/>
-+ * This can be used to enable a map entry to make changes on the underlying
-+ * map, however this will probably mess up any iterators.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TiedMapEntry <K,V> implements Map.Entry<K, V>, KeyValue<K, V>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -8453869361373831205L;
-+
-+    /**
-+     * The map underlying the entry/iterator
-+     */
-+    private final Map<K, V> map;
-+    /**
-+     * The key
-+     */
-+    private final K key;
-+
-+    /**
-+     * Constructs a new entry with the given Map and key.
-+     *
-+     * @param map the map
-+     * @param key the key
-+     */
-+    public TiedMapEntry(Map<K, V> map, K key) {
-+        super();
-+        this.map = map;
-+        this.key = key;
-+    }
-+
-+    // Map.Entry interface
-+    //-------------------------------------------------------------------------
-+    /**
-+     * Gets the key of this entry
-+     *
-+     * @return the key
-+     */
-+    public K getKey() {
-+        return key;
-+    }
-+
-+    /**
-+     * Gets the value of this entry direct from the map.
-+     *
-+     * @return the value
-+     */
-+    public V getValue() {
-+        return map.get(key);
-+    }
-+
-+    /**
-+     * Sets the value associated with the key direct onto the map.
-+     *
-+     * @param value the new value
-+     * @return the old value
-+     * @throws IllegalArgumentException if the value is set to this map entry
-+     */
-+    public V setValue(V value) {
-+        if ((Object) value == this) {
-+            throw new IllegalArgumentException("Cannot set value to this map entry");
-+        }
-+
-+        return map.put(key, value);
-+    }
-+
-+    /**
-+     * Compares this Map Entry with another Map Entry.
-+     * <p/>
-+     * Implemented per API documentation of {@link java.util.Map.Entry#equals(Object)}
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal key and value
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof Map.Entry == false) {
-+            return false;
-+        }
-+        Map.Entry other = (Map.Entry) obj;
-+        Object value = getValue();
-+        return (key == null ? other.getKey() == null : key.equals(other.getKey())) && (value == null ? other.getValue() == null : value.equals(other.getValue()));
-+    }
-+
-+    /**
-+     * Gets a hashCode compatible with the equals method.
-+     * <p/>
-+     * Implemented per API documentation of {@link java.util.Map.Entry#hashCode()}
-+     *
-+     * @return a suitable hash code
-+     */
-+    public int hashCode() {
-+        Object value = getValue();
-+        return (getKey() == null ? 0 : getKey().hashCode()) ^ (value == null ? 0 : value.hashCode());
-+    }
-+
-+    /**
-+     * Gets a string version of the entry.
-+     *
-+     * @return entry as a string
-+     */
-+    public String toString() {
-+        return getKey() + "=" + getValue();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/UnmodifiableMapEntry.java
-@@ -0,0 +1,75 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.keyvalue;
-+
-+import org.apache.commons.collections15.KeyValue;
-+import org.apache.commons.collections15.Unmodifiable;
-+
-+import java.util.Map;
-+
-+/**
-+ * A {@link java.util.Map.Entry} that throws UnsupportedOperationException
-+ * when <code>setValue</code> is called.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableMapEntry <K,V> extends AbstractMapEntry<K, V> implements Unmodifiable {
-+
-+    /**
-+     * Constructs a new entry with the specified key and given value.
-+     *
-+     * @param key   the key for the entry, may be null
-+     * @param value the value for the entry, may be null
-+     */
-+    public UnmodifiableMapEntry(final K key, final V value) {
-+        super(key, value);
-+    }
-+
-+    /**
-+     * Constructs a new entry from the specified KeyValue.
-+     *
-+     * @param pair the pair to copy, must not be null
-+     * @throws NullPointerException if the entry is null
-+     */
-+    public UnmodifiableMapEntry(final KeyValue<K, V> pair) {
-+        super(pair.getKey(), pair.getValue());
-+    }
-+
-+    /**
-+     * Constructs a new entry from the specified MapEntry.
-+     *
-+     * @param entry the entry to copy, must not be null
-+     * @throws NullPointerException if the entry is null
-+     */
-+    public UnmodifiableMapEntry(final Map.Entry<K, V> entry) {
-+        super(entry.getKey(), entry.getValue());
-+    }
-+
-+    /**
-+     * Throws UnsupportedOperationException.
-+     *
-+     * @param value the new value
-+     * @return the previous value
-+     * @throws UnsupportedOperationException always
-+     */
-+    public V setValue(V value) {
-+        throw new UnsupportedOperationException("setValue() is not supported");
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/keyvalue/package.html
-@@ -0,0 +1,29 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:32 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of collection and map related key/value classes.
-+These are usually used in maps, however they can be used as data holders in any collection.
-+<p>
-+The following key/value designs are included:
-+<ul>
-+<li>Map Entry - various map entry implementations
-+<li>KeyValue - a key and value pair, without map entry semantics
-+<li>MultiKey - a holder of multiple keys tied together
-+</ul>
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/AbstractLinkedList.java
-@@ -0,0 +1,1018 @@
-+// GenericsNote: Converted with possible improvements noted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.OrderedIterator;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.lang.reflect.Array;
-+import java.util.*;
-+
-+/**
-+ * An abstract implementation of a linked list which provides numerous points for
-+ * subclasses to override.
-+ * <p/>
-+ * Overridable methods are provided to change the storage node and to change how
-+ * nodes are added to and removed. Hopefully, all you need for unusual subclasses
-+ * is here.
-+ *
-+ * @author Rich Dougherty
-+ * @author Phil Steitz
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractLinkedList <E> implements List<E> {
-+
-+    /*
-+     * Implementation notes:
-+     * - a standard circular doubly-linked list
-+     * - a marker node is stored to mark the start and the end of the list
-+     * - node creation and removal always occurs through createNode() and
-+     *   removeNode().
-+     * - a modification count is kept, with the same semantics as
-+     * {@link java.util.LinkedList}.
-+     * - respects {@link AbstractList#modCount}
-+     */
-+
-+    /**
-+     * A {@link Node} which indicates the start and end of the list and does not
-+     * hold a value. The value of <code>next</code> is the first item in the
-+     * list. The value of of <code>previous</code> is the last item in the list.
-+     */
-+    protected transient Node<E> header;
-+    /**
-+     * The size of the list
-+     */
-+    protected transient int size;
-+    /**
-+     * Modification count for iterators
-+     */
-+    protected transient int modCount;
-+
-+    /**
-+     * Constructor that does nothing intended for deserialization.
-+     * <p/>
-+     * If this constructor is used by a serializable subclass then the init()
-+     * method must be called.
-+     */
-+    protected AbstractLinkedList() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a list copying data from the specified collection.
-+     *
-+     * @param coll the collection to copy
-+     */
-+    protected AbstractLinkedList(Collection<E> coll) {
-+        super();
-+        init();
-+        addAll(coll);
-+    }
-+
-+    /**
-+     * The equivalent of a default constructor, broken out so it can be called
-+     * by any constructor and by <code>readObject</code>.
-+     * Subclasses which override this method should make sure they call super,
-+     * so the list is initialised properly.
-+     */
-+    protected void init() {
-+        header = createHeaderNode();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public int size() {
-+        return size;
-+    }
-+
-+    public boolean isEmpty() {
-+        return (size() == 0);
-+    }
-+
-+    public E get(int index) {
-+        Node<E> node = getNode(index, false);
-+        return node.getValue();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return listIterator();
-+    }
-+
-+    public ListIterator<E> listIterator() {
-+        return new LinkedListIterator<E>(this, 0);
-+    }
-+
-+    public ListIterator<E> listIterator(int fromIndex) {
-+        return new LinkedListIterator<E>(this, fromIndex);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public int indexOf(Object value) {
-+        int i = 0;
-+        for (Node<E> node = header.next; node != header; node = node.next) {
-+            if (isEqualValue(node.getValue(), (E) value)) {
-+                return i;
-+            }
-+            i++;
-+        }
-+        return -1;
-+    }
-+
-+    public int lastIndexOf(Object value) {
-+        int i = size - 1;
-+        for (Node<E> node = header.previous; node != header; node = node.previous) {
-+            if (isEqualValue(node.getValue(), (E) value)) {
-+                return i;
-+            }
-+            i--;
-+        }
-+        return -1;
-+    }
-+
-+    public boolean contains(Object value) {
-+        return indexOf(value) != -1;
-+    }
-+
-+    public boolean containsAll(Collection<?> coll) {
-+        Iterator it = coll.iterator();
-+        while (it.hasNext()) {
-+            if (contains(it.next()) == false) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Object[] toArray() {
-+        return toArray(new Object[size]);
-+    }
-+
-+    public <T> T[] toArray(T[] array) {
-+        // Extend the array if needed
-+        if (array.length < size) {
-+            Class componentType = array.getClass().getComponentType();
-+            array = (T[]) Array.newInstance(componentType, size);
-+        }
-+        // Copy the values into the array
-+        int i = 0;
-+        for (Node<E> node = header.next; node != header; node = node.next, i++) {
-+            // Can do no better than cast through Object here.
-+            array[i] = (T) (Object) node.getValue();
-+        }
-+        // Set the value after the last value to null
-+        if (array.length > size) {
-+            array[size] = null;
-+        }
-+        return array;
-+    }
-+
-+    /**
-+     * Gets a sublist of the main list.
-+     *
-+     * @param fromIndexInclusive the index to start from
-+     * @param toIndexExclusive   the index to end at
-+     * @return the new sublist
-+     */
-+    public List<E> subList(int fromIndexInclusive, int toIndexExclusive) {
-+        return new LinkedSubList<E>(this, fromIndexInclusive, toIndexExclusive);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E value) {
-+        addLast(value);
-+        return true;
-+    }
-+
-+    public void add(int index, E value) {
-+        Node<E> node = getNode(index, true);
-+        addNodeBefore(node, value);
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        return addAll(size, coll);
-+    }
-+
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        Node<E> node = getNode(index, true);
-+        for (Iterator itr = coll.iterator(); itr.hasNext();) {
-+            Object value = itr.next();
-+            addNodeBefore(node, (E) value);
-+        }
-+        return true;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E remove(int index) {
-+        Node<E> node = getNode(index, false);
-+        E oldValue = node.getValue();
-+        removeNode(node);
-+        return oldValue;
-+    }
-+
-+    public boolean remove(Object value) {
-+        for (Node<E> node = header.next; node != header; node = node.next) {
-+            if (isEqualValue(node.getValue(), (E) value)) {
-+                removeNode(node);
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        boolean modified = false;
-+        Iterator it = iterator();
-+        while (it.hasNext()) {
-+            if (coll.contains(it.next())) {
-+                it.remove();
-+                modified = true;
-+            }
-+        }
-+        return modified;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean retainAll(Collection<?> coll) {
-+        boolean modified = false;
-+        Iterator it = iterator();
-+        while (it.hasNext()) {
-+            if (coll.contains(it.next()) == false) {
-+                it.remove();
-+                modified = true;
-+            }
-+        }
-+        return modified;
-+    }
-+
-+    public E set(int index, E value) {
-+        Node<E> node = getNode(index, false);
-+        E oldValue = node.getValue();
-+        updateNode(node, value);
-+        return oldValue;
-+    }
-+
-+    public void clear() {
-+        removeAllNodes();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E getFirst() {
-+        Node<E> node = header.next;
-+        if (node == header) {
-+            throw new NoSuchElementException();
-+        }
-+        return node.getValue();
-+    }
-+
-+    public E getLast() {
-+        Node<E> node = header.previous;
-+        if (node == header) {
-+            throw new NoSuchElementException();
-+        }
-+        return node.getValue();
-+    }
-+
-+    public boolean addFirst(E o) {
-+        addNodeAfter(header, o);
-+        return true;
-+    }
-+
-+    public boolean addLast(E o) {
-+        addNodeBefore(header, o);
-+        return true;
-+    }
-+
-+    public E removeFirst() {
-+        Node<E> node = header.next;
-+        if (node == header) {
-+            throw new NoSuchElementException();
-+        }
-+        E oldValue = node.getValue();
-+        removeNode(node);
-+        return oldValue;
-+    }
-+
-+    public E removeLast() {
-+        Node<E> node = header.previous;
-+        if (node == header) {
-+            throw new NoSuchElementException();
-+        }
-+        E oldValue = node.getValue();
-+        removeNode(node);
-+        return oldValue;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof List == false) {
-+            return false;
-+        }
-+        List other = (List) obj;
-+        if (other.size() != size()) {
-+            return false;
-+        }
-+        ListIterator it1 = listIterator();
-+        ListIterator it2 = other.listIterator();
-+        while (it1.hasNext() && it2.hasNext()) {
-+            Object o1 = it1.next();
-+            Object o2 = it2.next();
-+            if (!(o1 == null ? o2 == null : o1.equals(o2)))
-+                return false;
-+        }
-+        return !(it1.hasNext() || it2.hasNext());
-+    }
-+
-+    public int hashCode() {
-+        int hashCode = 1;
-+        Iterator it = iterator();
-+        while (it.hasNext()) {
-+            Object obj = it.next();
-+            hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
-+        }
-+        return hashCode;
-+    }
-+
-+    public String toString() {
-+        if (size() == 0) {
-+            return "[]";
-+        }
-+        StringBuffer buf = new StringBuffer(16 * size());
-+        buf.append("[");
-+
-+        Iterator it = iterator();
-+        boolean hasNext = it.hasNext();
-+        while (hasNext) {
-+            Object value = it.next();
-+            buf.append(value == this ? "(this Collection)" : value);
-+            hasNext = it.hasNext();
-+            if (hasNext) {
-+                buf.append(", ");
-+            }
-+        }
-+        buf.append("]");
-+        return buf.toString();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares two values for equals.
-+     * This implementation uses the equals method.
-+     * Subclasses can override this to match differently.
-+     *
-+     * @param value1 the first value to compare, may be null
-+     * @param value2 the second value to compare, may be null
-+     * @return true if equal
-+     */
-+    protected boolean isEqualValue(E value1, E value2) {
-+        return (value1 == value2 || (value1 == null ? false : value1.equals(value2)));
-+    }
-+
-+    /**
-+     * Updates the node with a new value.
-+     * This implementation sets the value on the node.
-+     * Subclasses can override this to record the change.
-+     *
-+     * @param node  node to update
-+     * @param value new value of the node
-+     */
-+    protected void updateNode(Node<E> node, E value) {
-+        node.setValue(value);
-+    }
-+
-+    /**
-+     * Creates a new node with previous, next and element all set to null.
-+     * This implementation creates a new empty Node.
-+     * Subclasses can override this to create a different class.
-+     *
-+     * @return newly created node
-+     */
-+    protected Node<E> createHeaderNode() {
-+        return new Node<E>();
-+    }
-+
-+    /**
-+     * Creates a new node with the specified properties.
-+     * This implementation creates a new Node with data.
-+     * Subclasses can override this to create a different class.
-+     *
-+     * @param value value of the new node
-+     */
-+    protected Node<E> createNode(E value) {
-+        return new Node<E>(value);
-+    }
-+
-+    /**
-+     * Creates a new node with the specified object as its
-+     * <code>value</code> and inserts it before <code>node</code>.
-+     * <p/>
-+     * This implementation uses {@link #createNode(Object)} and
-+     * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
-+     *
-+     * @param node  node to insert before
-+     * @param value value of the newly added node
-+     * @throws NullPointerException if <code>node</code> is null
-+     */
-+    protected void addNodeBefore(Node<E> node, E value) {
-+        Node newNode = createNode(value);
-+        addNode(newNode, node);
-+    }
-+
-+    /**
-+     * Creates a new node with the specified object as its
-+     * <code>value</code> and inserts it after <code>node</code>.
-+     * <p/>
-+     * This implementation uses {@link #createNode(Object)} and
-+     * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
-+     *
-+     * @param node  node to insert after
-+     * @param value value of the newly added node
-+     * @throws NullPointerException if <code>node</code> is null
-+     */
-+    protected void addNodeAfter(Node<E> node, E value) {
-+        Node<E> newNode = createNode(value);
-+        addNode(newNode, node.next);
-+    }
-+
-+    /**
-+     * Inserts a new node into the list.
-+     *
-+     * @param nodeToInsert     new node to insert
-+     * @param insertBeforeNode node to insert before
-+     * @throws NullPointerException if either node is null
-+     */
-+    protected void addNode(Node<E> nodeToInsert, Node<E> insertBeforeNode) {
-+        nodeToInsert.next = insertBeforeNode;
-+        nodeToInsert.previous = insertBeforeNode.previous;
-+        insertBeforeNode.previous.next = nodeToInsert;
-+        insertBeforeNode.previous = nodeToInsert;
-+        size++;
-+        modCount++;
-+    }
-+
-+    /**
-+     * Removes the specified node from the list.
-+     *
-+     * @param node the node to remove
-+     * @throws NullPointerException if <code>node</code> is null
-+     */
-+    protected void removeNode(Node<E> node) {
-+        node.previous.next = node.next;
-+        node.next.previous = node.previous;
-+        size--;
-+        modCount++;
-+    }
-+
-+    /**
-+     * Removes all nodes by resetting the circular list marker.
-+     */
-+    protected void removeAllNodes() {
-+        header.next = header;
-+        header.previous = header;
-+        size = 0;
-+        modCount++;
-+    }
-+
-+    /**
-+     * Gets the node at a particular index.
-+     *
-+     * @param index            the index, starting from 0
-+     * @param endMarkerAllowed whether or not the end marker can be returned if
-+     *                         startIndex is set to the list's size
-+     * @throws IndexOutOfBoundsException if the index is less than 0; equal to
-+     *                                   the size of the list and endMakerAllowed is false; or greater than the
-+     *                                   size of the list
-+     */
-+    protected Node<E> getNode(int index, boolean endMarkerAllowed) throws IndexOutOfBoundsException {
-+        // Check the index is within the bounds
-+        if (index < 0) {
-+            throw new IndexOutOfBoundsException("Couldn't get the node: " + "index (" + index + ") less than zero.");
-+        }
-+        if (!endMarkerAllowed && index == size) {
-+            throw new IndexOutOfBoundsException("Couldn't get the node: " + "index (" + index + ") is the size of the list.");
-+        }
-+        if (index > size) {
-+            throw new IndexOutOfBoundsException("Couldn't get the node: " + "index (" + index + ") greater than the size of the " + "list (" + size + ").");
-+        }
-+        // Search the list and get the node
-+        Node<E> node;
-+        if (index < (size / 2)) {
-+            // Search forwards
-+            node = header.next;
-+            for (int currentIndex = 0; currentIndex < index; currentIndex++) {
-+                node = node.next;
-+            }
-+        } else {
-+            // Search backwards
-+            node = header;
-+            for (int currentIndex = size; currentIndex > index; currentIndex--) {
-+                node = node.previous;
-+            }
-+        }
-+        return node;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Creates an iterator for the sublist.
-+     *
-+     * @param subList the sublist to get an iterator for
-+     */
-+    protected Iterator<E> createSubListIterator(LinkedSubList<E> subList) {
-+        return createSubListListIterator(subList, 0);
-+    }
-+
-+    /**
-+     * Creates a list iterator for the sublist.
-+     *
-+     * @param subList   the sublist to get an iterator for
-+     * @param fromIndex the index to start from, relative to the sublist
-+     */
-+    protected ListIterator<E> createSubListListIterator(LinkedSubList<E> subList, int fromIndex) {
-+        return new LinkedSubListIterator(subList, fromIndex);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Serializes the data held in this object to the stream specified.
-+     * <p/>
-+     * The first serializable subclass must call this method from
-+     * <code>writeObject</code>.
-+     */
-+    protected void doWriteObject(ObjectOutputStream outputStream) throws IOException {
-+        // Write the size so we know how many nodes to read back
-+        outputStream.writeInt(size());
-+        for (Iterator itr = iterator(); itr.hasNext();) {
-+            outputStream.writeObject(itr.next());
-+        }
-+    }
-+
-+    /**
-+     * Deserializes the data held in this object to the stream specified.
-+     * <p/>
-+     * The first serializable subclass must call this method from
-+     * <code>readObject</code>.
-+     */
-+    protected void doReadObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
-+        init();
-+        int size = inputStream.readInt();
-+        for (int i = 0; i < size; i++) {
-+            add((E) inputStream.readObject());
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A node within the linked list.
-+     * <p/>
-+     * From Commons Collections 3.1, all access to the <code>value</code> property
-+     * is via the methods on this class.
-+     */
-+    protected static class Node <T> {
-+
-+        /**
-+         * A pointer to the node before this node
-+         */
-+        protected Node<T> previous;
-+        /**
-+         * A pointer to the node after this node
-+         */
-+        protected Node<T> next;
-+        /**
-+         * The object contained within this node
-+         */
-+        protected T value;
-+
-+        /**
-+         * Constructs a new header node.
-+         */
-+        protected Node() {
-+            super();
-+            previous = this;
-+            next = this;
-+        }
-+
-+        /**
-+         * Constructs a new node.
-+         *
-+         * @param value the value to store
-+         */
-+        protected Node(T value) {
-+            super();
-+            this.value = value;
-+        }
-+
-+        /**
-+         * Constructs a new node.
-+         *
-+         * @param previous the previous node in the list
-+         * @param next     the next node in the list
-+         * @param value    the value to store
-+         */
-+        protected Node(Node<T> previous, Node<T> next, T value) {
-+            super();
-+            this.previous = previous;
-+            this.next = next;
-+            this.value = value;
-+        }
-+
-+        /**
-+         * Gets the value of the node.
-+         *
-+         * @return the value
-+         * @since Commons Collections 3.1
-+         */
-+        protected T getValue() {
-+            return value;
-+        }
-+
-+        /**
-+         * Sets the value of the node.
-+         *
-+         * @param value the value
-+         * @since Commons Collections 3.1
-+         */
-+        protected void setValue(T value) {
-+            this.value = value;
-+        }
-+
-+        /**
-+         * Gets the previous node.
-+         *
-+         * @return the previous node
-+         * @since Commons Collections 3.1
-+         */
-+        protected Node<T> getPreviousNode() {
-+            return previous;
-+        }
-+
-+        /**
-+         * Sets the previous node.
-+         *
-+         * @param previous the previous node
-+         * @since Commons Collections 3.1
-+         */
-+        protected void setPreviousNode(Node<T> previous) {
-+            this.previous = previous;
-+        }
-+
-+        /**
-+         * Gets the next node.
-+         *
-+         * @return the next node
-+         * @since Commons Collections 3.1
-+         */
-+        protected Node<T> getNextNode() {
-+            return next;
-+        }
-+
-+        /**
-+         * Sets the next node.
-+         *
-+         * @param next the next node
-+         * @since Commons Collections 3.1
-+         */
-+        protected void setNextNode(Node<T> next) {
-+            this.next = next;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A list iterator over the linked list.
-+     */
-+    protected static class LinkedListIterator <E> implements ListIterator<E>, OrderedIterator<E> {
-+
-+        /**
-+         * The parent list
-+         */
-+        protected final AbstractLinkedList<E> parent;
-+
-+        /**
-+         * The node that will be returned by {@link #next()}. If this is equal
-+         * to {@link AbstractLinkedList#header} then there are no more values to return.
-+         */
-+        protected Node<E> next;
-+
-+        /**
-+         * The index of {@link #next}.
-+         */
-+        protected int nextIndex;
-+
-+        /**
-+         * The last node that was returned by {@link #next()} or {@link
-+         * #previous()}. Set to <code>null</code> if {@link #next()} or {@link
-+         * #previous()} haven't been called, or if the node has been removed
-+         * with {@link #remove()} or a new node added with {@link #add(Object)}.
-+         * Should be accessed through {@link #getLastNodeReturned()} to enforce
-+         * this behaviour.
-+         */
-+        protected Node<E> current;
-+
-+        /**
-+         * The modification count that the list is expected to have. If the list
-+         * doesn't have this count, then a
-+         * {@link java.util.ConcurrentModificationException} may be thrown by
-+         * the operations.
-+         */
-+        protected int expectedModCount;
-+
-+        /**
-+         * Create a ListIterator for a list.
-+         *
-+         * @param parent    the parent list
-+         * @param fromIndex the index to start at
-+         */
-+        protected LinkedListIterator(AbstractLinkedList<E> parent, int fromIndex) throws IndexOutOfBoundsException {
-+            super();
-+            this.parent = parent;
-+            this.expectedModCount = parent.modCount;
-+            this.next = parent.getNode(fromIndex, true);
-+            this.nextIndex = fromIndex;
-+        }
-+
-+        /**
-+         * Checks the modification count of the list is the value that this
-+         * object expects.
-+         *
-+         * @throws ConcurrentModificationException
-+         *          If the list's modification
-+         *          count isn't the value that was expected.
-+         */
-+        protected void checkModCount() {
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+        }
-+
-+        /**
-+         * Gets the last node returned.
-+         *
-+         * @throws IllegalStateException If {@link #next()} or
-+         *                               {@link #previous()} haven't been called, or if the node has been removed
-+         *                               with {@link #remove()} or a new node added with {@link #add(Object)}.
-+         */
-+        protected Node<E> getLastNodeReturned() throws IllegalStateException {
-+            if (current == null) {
-+                throw new IllegalStateException();
-+            }
-+            return current;
-+        }
-+
-+        public boolean hasNext() {
-+            return next != parent.header;
-+        }
-+
-+        public E next() {
-+            checkModCount();
-+            if (!hasNext()) {
-+                throw new NoSuchElementException("No element at index " + nextIndex + ".");
-+            }
-+            E value = next.getValue();
-+            current = next;
-+            next = next.next;
-+            nextIndex++;
-+            return value;
-+        }
-+
-+        public boolean hasPrevious() {
-+            return next.previous != parent.header;
-+        }
-+
-+        public E previous() {
-+            checkModCount();
-+            if (!hasPrevious()) {
-+                throw new NoSuchElementException("Already at start of list.");
-+            }
-+            next = next.previous;
-+            E value = next.getValue();
-+            current = next;
-+            nextIndex--;
-+            return value;
-+        }
-+
-+        public int nextIndex() {
-+            return nextIndex;
-+        }
-+
-+        public int previousIndex() {
-+            // not normally overridden, as relative to nextIndex()
-+            return nextIndex() - 1;
-+        }
-+
-+        public void remove() {
-+            checkModCount();
-+            parent.removeNode(getLastNodeReturned());
-+            current = null;
-+            nextIndex--;
-+            expectedModCount++;
-+        }
-+
-+        public void set(E obj) {
-+            checkModCount();
-+            getLastNodeReturned().setValue(obj);
-+        }
-+
-+        public void add(E obj) {
-+            checkModCount();
-+            parent.addNodeBefore(next, obj);
-+            current = null;
-+            nextIndex++;
-+            expectedModCount++;
-+        }
-+
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A list iterator over the linked sub list.
-+     */
-+    protected static class LinkedSubListIterator <E> extends LinkedListIterator<E> {
-+
-+        /**
-+         * The parent list
-+         */
-+        protected final LinkedSubList<E> sub;
-+
-+        protected LinkedSubListIterator(LinkedSubList<E> sub, int startIndex) {
-+            super(sub.parent, startIndex + sub.offset);
-+            this.sub = sub;
-+        }
-+
-+        public boolean hasNext() {
-+            return (nextIndex() < sub.size);
-+        }
-+
-+        public boolean hasPrevious() {
-+            return (previousIndex() >= 0);
-+        }
-+
-+        public int nextIndex() {
-+            return (super.nextIndex() - sub.offset);
-+        }
-+
-+        public void add(E obj) {
-+            super.add(obj);
-+            sub.expectedModCount = parent.modCount;
-+            sub.size++;
-+        }
-+
-+        public void remove() {
-+            super.remove();
-+            sub.expectedModCount = parent.modCount;
-+            sub.size--;
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * The sublist implementation for AbstractLinkedList.
-+     */
-+    protected static class LinkedSubList <E> extends AbstractList<E> {
-+        /**
-+         * The main list
-+         */
-+        private AbstractLinkedList<E> parent;
-+        /**
-+         * Offset from the main list
-+         */
-+        private int offset;
-+        /**
-+         * Sublist size
-+         */
-+        private int size;
-+        /**
-+         * Sublist modCount
-+         */
-+        private int expectedModCount;
-+
-+        protected LinkedSubList(AbstractLinkedList<E> parent, int fromIndex, int toIndex) {
-+            if (fromIndex < 0) {
-+                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
-+            }
-+            if (toIndex > parent.size()) {
-+                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
-+            }
-+            if (fromIndex > toIndex) {
-+                throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
-+            }
-+            this.parent = parent;
-+            this.offset = fromIndex;
-+            this.size = toIndex - fromIndex;
-+            this.expectedModCount = parent.modCount;
-+        }
-+
-+        public int size() {
-+            checkModCount();
-+            return size;
-+        }
-+
-+        public E get(int index) {
-+            rangeCheck(index, size);
-+            checkModCount();
-+            return parent.get(index + offset);
-+        }
-+
-+        public void add(int index, E obj) {
-+            rangeCheck(index, size + 1);
-+            checkModCount();
-+            parent.add(index + offset, obj);
-+            expectedModCount = parent.modCount;
-+            size++;
-+            LinkedSubList.this.modCount++;
-+        }
-+
-+        public E remove(int index) {
-+            rangeCheck(index, size);
-+            checkModCount();
-+            E result = parent.remove(index + offset);
-+            expectedModCount = parent.modCount;
-+            size--;
-+            LinkedSubList.this.modCount++;
-+            return result;
-+        }
-+
-+        public boolean addAll(Collection<? extends E> coll) {
-+            return addAll(size, coll);
-+        }
-+
-+        public boolean addAll(int index, Collection<? extends E> coll) {
-+            rangeCheck(index, size + 1);
-+            int cSize = coll.size();
-+            if (cSize == 0) {
-+                return false;
-+            }
-+
-+            checkModCount();
-+            parent.addAll(offset + index, coll);
-+            expectedModCount = parent.modCount;
-+            size += cSize;
-+            LinkedSubList.this.modCount++;
-+            return true;
-+        }
-+
-+        public E set(int index, E obj) {
-+            rangeCheck(index, size);
-+            checkModCount();
-+            return parent.set(index + offset, obj);
-+        }
-+
-+        public void clear() {
-+            checkModCount();
-+            Iterator it = iterator();
-+            while (it.hasNext()) {
-+                it.next();
-+                it.remove();
-+            }
-+        }
-+
-+        public Iterator<E> iterator() {
-+            checkModCount();
-+            return parent.createSubListIterator(this);
-+        }
-+
-+        public ListIterator<E> listIterator(final int index) {
-+            rangeCheck(index, size + 1);
-+            checkModCount();
-+            return parent.createSubListListIterator(this, index);
-+        }
-+
-+        public List subList(int fromIndexInclusive, int toIndexExclusive) {
-+            return new LinkedSubList(parent, fromIndexInclusive + offset, toIndexExclusive + offset);
-+        }
-+
-+        protected void rangeCheck(int index, int beyond) {
-+            if (index < 0 || index >= beyond) {
-+                throw new IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + size + "'");
-+            }
-+        }
-+
-+        protected void checkModCount() {
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/AbstractListDecorator.java
-@@ -0,0 +1,105 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.collection.AbstractCollectionDecorator;
-+
-+import java.util.Collection;
-+import java.util.List;
-+import java.util.ListIterator;
-+
-+/**
-+ * Decorates another <code>List</code> to provide additional behaviour.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated list.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractListDecorator <E> extends AbstractCollectionDecorator<E> implements List<E> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractListDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    protected AbstractListDecorator(List<E> list) {
-+        super(list);
-+    }
-+
-+    /**
-+     * Gets the list being decorated.
-+     *
-+     * @return the decorated list
-+     */
-+    protected List<E> getList() {
-+        return (List<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void add(int index, E object) {
-+        getList().add(index, object);
-+    }
-+
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        return getList().addAll(index, coll);
-+    }
-+
-+    public E get(int index) {
-+        return getList().get(index);
-+    }
-+
-+    public int indexOf(Object object) {
-+        return getList().indexOf(object);
-+    }
-+
-+    public int lastIndexOf(Object object) {
-+        return getList().lastIndexOf(object);
-+    }
-+
-+    public ListIterator<E> listIterator() {
-+        return getList().listIterator();
-+    }
-+
-+    public ListIterator<E> listIterator(int index) {
-+        return getList().listIterator(index);
-+    }
-+
-+    public E remove(int index) {
-+        return getList().remove(index);
-+    }
-+
-+    public E set(int index, E object) {
-+        return getList().set(index, object);
-+    }
-+
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        return getList().subList(fromIndex, toIndex);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/AbstractSerializableListDecorator.java
-@@ -0,0 +1,70 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.List;
-+
-+/**
-+ * Serializable subclass of AbstractListDecorator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @since Commons Collections 3.1
-+ */
-+public abstract class AbstractSerializableListDecorator <E> extends AbstractListDecorator<E> implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 2684959196747496299L;
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected AbstractSerializableListDecorator(List<E> list) {
-+        super(list);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the list out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(collection);
-+    }
-+
-+    /**
-+     * Read the list in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        collection = (Collection<E>) in.readObject();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/CursorableLinkedList.java
-@@ -0,0 +1,500 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.lang.ref.WeakReference;
-+import java.util.*;
-+
-+/**
-+ * A <code>List</code> implementation with a <code>ListIterator</code> that
-+ * allows concurrent modifications to the underlying list.
-+ * <p/>
-+ * This implementation supports all of the optional {@link List} operations.
-+ * It extends <code>AbstractLinkedList</code> and thus provides the
-+ * stack/queue/dequeue operations available in {@link java.util.LinkedList}.
-+ * <p/>
-+ * The main feature of this class is the ability to modify the list and the
-+ * iterator at the same time. Both the {@link #listIterator()} and {@link #cursor()}
-+ * methods provides access to a <code>Cursor</code> instance which extends
-+ * <code>ListIterator</code>. The cursor allows changes to the list concurrent
-+ * with changes to the iterator. Note that the {@link #iterator()} method and
-+ * sublists  do <b>not</b> provide this cursor behaviour.
-+ * <p/>
-+ * The <code>Cursor</code> class is provided partly for backwards compatibility
-+ * and partly because it allows the cursor to be directly closed. Closing the
-+ * cursor is optional because references are held via a <code>WeakReference</code>.
-+ * For most purposes, simply modify the iterator and list at will, and then let
-+ * the garbage collector to the rest.
-+ * <p/>
-+ * <b>Note that this implementation is not synchronized.</b>
-+ *
-+ * @author Rodney Waldhoff
-+ * @author Janek Bogucki
-+ * @author Simon Kitching
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @see java.util.LinkedList
-+ * @since Commons Collections 1.0
-+ */
-+public class CursorableLinkedList <E> extends AbstractLinkedList<E> implements Serializable {
-+
-+    /**
-+     * Ensure serialization compatibility
-+     */
-+    private static final long serialVersionUID = 8836393098519411393L;
-+
-+    /**
-+     * A list of the cursor currently open on this list
-+     */
-+    protected transient List<WeakReference<Cursor<E>>> cursors = new ArrayList<WeakReference<Cursor<E>>>();
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that creates.
-+     */
-+    public CursorableLinkedList() {
-+        super();
-+        init(); // must call init() as use super();
-+    }
-+
-+    /**
-+     * Constructor that copies the specified collection
-+     *
-+     * @param coll the collection to copy
-+     */
-+    public CursorableLinkedList(Collection<E> coll) {
-+        super(coll);
-+    }
-+
-+    /**
-+     * The equivalent of a default constructor called
-+     * by any constructor and by <code>readObject</code>.
-+     */
-+    protected void init() {
-+        super.init();
-+        cursors = new ArrayList<WeakReference<Cursor<E>>>();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns an iterator that does <b>not</b> support concurrent modification.
-+     * <p/>
-+     * If the underlying list is modified while iterating using this iterator
-+     * a ConcurrentModificationException will occur.
-+     * The cursor behaviour is available via {@link #listIterator()}.
-+     *
-+     * @return a new iterator that does <b>not</b> support concurrent modification
-+     */
-+    public Iterator<E> iterator() {
-+        return super.listIterator(0);
-+    }
-+
-+    /**
-+     * Returns a cursor iterator that allows changes to the underlying list in parallel.
-+     * <p/>
-+     * The cursor enables iteration and list changes to occur in any order without
-+     * invalidating the iterator (from one thread). When elements are added to the
-+     * list, an event is fired to all active cursors enabling them to adjust to the
-+     * change in the list.
-+     * <p/>
-+     * When the "current" (i.e., last returned by {@link ListIterator#next}
-+     * or {@link ListIterator#previous}) element of the list is removed,
-+     * the cursor automatically adjusts to the change (invalidating the
-+     * last returned value such that it cannot be removed).
-+     *
-+     * @return a new cursor iterator
-+     */
-+    public ListIterator<E> listIterator() {
-+        return cursor(0);
-+    }
-+
-+    /**
-+     * Returns a cursor iterator that allows changes to the underlying list in parallel.
-+     * <p/>
-+     * The cursor enables iteration and list changes to occur in any order without
-+     * invalidating the iterator (from one thread). When elements are added to the
-+     * list, an event is fired to all active cursors enabling them to adjust to the
-+     * change in the list.
-+     * <p/>
-+     * When the "current" (i.e., last returned by {@link ListIterator#next}
-+     * or {@link ListIterator#previous}) element of the list is removed,
-+     * the cursor automatically adjusts to the change (invalidating the
-+     * last returned value such that it cannot be removed).
-+     *
-+     * @param fromIndex the index to start from
-+     * @return a new cursor iterator
-+     */
-+    public ListIterator<E> listIterator(int fromIndex) {
-+        return cursor(fromIndex);
-+    }
-+
-+    /**
-+     * Returns a {@link Cursor} for iterating through the elements of this list.
-+     * <p/>
-+     * A <code>Cursor</code> is a <code>ListIterator</code> with an additional
-+     * <code>close()</code> method. Calling this method immediately discards the
-+     * references to the cursor. If it is not called, then the garbage collector
-+     * will still remove the reference as it is held via a <code>WeakReference</code>.
-+     * <p/>
-+     * The cursor enables iteration and list changes to occur in any order without
-+     * invalidating the iterator (from one thread). When elements are added to the
-+     * list, an event is fired to all active cursors enabling them to adjust to the
-+     * change in the list.
-+     * <p/>
-+     * When the "current" (i.e., last returned by {@link ListIterator#next}
-+     * or {@link ListIterator#previous}) element of the list is removed,
-+     * the cursor automatically adjusts to the change (invalidating the
-+     * last returned value such that it cannot be removed).
-+     * <p/>
-+     * The {@link #listIterator()} method returns the same as this method, and can
-+     * be cast to a <code>Cursor</code> if the <code>close</code> method is required.
-+     *
-+     * @return a new cursor iterator
-+     */
-+    public CursorableLinkedList.Cursor<E> cursor() {
-+        return cursor(0);
-+    }
-+
-+    /**
-+     * Returns a {@link Cursor} for iterating through the elements of this list
-+     * starting from a specified index.
-+     * <p/>
-+     * A <code>Cursor</code> is a <code>ListIterator</code> with an additional
-+     * <code>close()</code> method. Calling this method immediately discards the
-+     * references to the cursor. If it is not called, then the garbage collector
-+     * will still remove the reference as it is held via a <code>WeakReference</code>.
-+     * <p/>
-+     * The cursor enables iteration and list changes to occur in any order without
-+     * invalidating the iterator (from one thread). When elements are added to the
-+     * list, an event is fired to all active cursors enabling them to adjust to the
-+     * change in the list.
-+     * <p/>
-+     * When the "current" (i.e., last returned by {@link ListIterator#next}
-+     * or {@link ListIterator#previous}) element of the list is removed,
-+     * the cursor automatically adjusts to the change (invalidating the
-+     * last returned value such that it cannot be removed).
-+     * <p/>
-+     * The {@link #listIterator(int)} method returns the same as this method, and can
-+     * be cast to a <code>Cursor</code> if the <code>close</code> method is required.
-+     *
-+     * @param fromIndex the index to start from
-+     * @return a new cursor iterator
-+     * @throws IndexOutOfBoundsException if the index is out of range
-+     *                                   (index < 0 || index > size()).
-+     */
-+    public CursorableLinkedList.Cursor<E> cursor(int fromIndex) {
-+        Cursor<E> cursor = new Cursor<E>(this, fromIndex);
-+        registerCursor(cursor);
-+        return cursor;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Updates the node with a new value.
-+     * This implementation sets the value on the node.
-+     * Subclasses can override this to record the change.
-+     *
-+     * @param node  node to update
-+     * @param value new value of the node
-+     */
-+    protected void updateNode(Node<E> node, E value) {
-+        super.updateNode(node, value);
-+        broadcastNodeChanged(node);
-+    }
-+
-+    /**
-+     * Inserts a new node into the list.
-+     *
-+     * @param nodeToInsert     new node to insert
-+     * @param insertBeforeNode node to insert before
-+     * @throws NullPointerException if either node is null
-+     */
-+    protected void addNode(Node<E> nodeToInsert, Node<E> insertBeforeNode) {
-+        super.addNode(nodeToInsert, insertBeforeNode);
-+        broadcastNodeInserted(nodeToInsert);
-+    }
-+
-+    /**
-+     * Removes the specified node from the list.
-+     *
-+     * @param node the node to remove
-+     * @throws NullPointerException if <code>node</code> is null
-+     */
-+    protected void removeNode(Node<E> node) {
-+        super.removeNode(node);
-+        broadcastNodeRemoved(node);
-+    }
-+
-+    /**
-+     * Removes all nodes by iteration.
-+     */
-+    protected void removeAllNodes() {
-+        if (size() > 0) {
-+            // superclass implementation would break all the iterators
-+            Iterator it = iterator();
-+            while (it.hasNext()) {
-+                it.next();
-+                it.remove();
-+            }
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Registers a cursor to be notified of changes to this list.
-+     *
-+     * @param cursor the cursor to register
-+     */
-+    protected void registerCursor(Cursor<E> cursor) {
-+        // We take this opportunity to clean the cursors list
-+        // of WeakReference objects to garbage-collected cursors.
-+        for (Iterator<WeakReference<Cursor<E>>> it = cursors.iterator(); it.hasNext();) {
-+            WeakReference<Cursor<E>> ref = it.next();
-+            if (ref.get() == null) {
-+                it.remove();
-+            }
-+        }
-+        cursors.add(new WeakReference<Cursor<E>>(cursor));
-+    }
-+
-+    /**
-+     * Deregisters a cursor from the list to be notified of changes.
-+     *
-+     * @param cursor the cursor to deregister
-+     */
-+    protected void unregisterCursor(Cursor<E> cursor) {
-+        for (Iterator it = cursors.iterator(); it.hasNext();) {
-+            WeakReference ref = (WeakReference) it.next();
-+            Cursor cur = (Cursor) ref.get();
-+            if (cur == null) {
-+                // some other unrelated cursor object has been 
-+                // garbage-collected; let's take the opportunity to
-+                // clean up the cursors list anyway..
-+                it.remove();
-+
-+            } else if (cur == cursor) {
-+                ref.clear();
-+                it.remove();
-+                break;
-+            }
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Informs all of my registered cursors that the specified
-+     * element was changed.
-+     *
-+     * @param node the node that was changed
-+     */
-+    protected void broadcastNodeChanged(Node<E> node) {
-+        Iterator it = cursors.iterator();
-+        while (it.hasNext()) {
-+            WeakReference ref = (WeakReference) it.next();
-+            Cursor cursor = (Cursor) ref.get();
-+            if (cursor == null) {
-+                it.remove(); // clean up list
-+            } else {
-+                cursor.nodeChanged(node);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Informs all of my registered cursors that the specified
-+     * element was just removed from my list.
-+     *
-+     * @param node the node that was changed
-+     */
-+    protected void broadcastNodeRemoved(Node<E> node) {
-+        Iterator it = cursors.iterator();
-+        while (it.hasNext()) {
-+            WeakReference ref = (WeakReference) it.next();
-+            Cursor cursor = (Cursor) ref.get();
-+            if (cursor == null) {
-+                it.remove(); // clean up list
-+            } else {
-+                cursor.nodeRemoved(node);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Informs all of my registered cursors that the specified
-+     * element was just added to my list.
-+     *
-+     * @param node the node that was changed
-+     */
-+    protected void broadcastNodeInserted(Node<E> node) {
-+        Iterator it = cursors.iterator();
-+        while (it.hasNext()) {
-+            WeakReference ref = (WeakReference) it.next();
-+            Cursor cursor = (Cursor) ref.get();
-+            if (cursor == null) {
-+                it.remove(); // clean up list
-+            } else {
-+                cursor.nodeInserted(node);
-+            }
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Serializes the data held in this object to the stream specified.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Deserializes the data held in this object to the stream specified.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * An extended <code>ListIterator</code> that allows concurrent changes to
-+     * the underlying list.
-+     */
-+    public static class Cursor <E> extends AbstractLinkedList.LinkedListIterator<E> {
-+        /**
-+         * Is the cursor valid (not closed)
-+         */
-+        boolean valid = true;
-+        /**
-+         * Is the next index valid
-+         */
-+        boolean nextIndexValid = true;
-+
-+        /**
-+         * Constructs a new cursor.
-+         *
-+         * @param index the index to start from
-+         */
-+        protected Cursor(CursorableLinkedList<E> parent, int index) {
-+            super(parent, index);
-+            valid = true;
-+        }
-+
-+        /**
-+         * Adds an object to the list.
-+         * The object added here will be the new 'previous' in the iterator.
-+         *
-+         * @param obj the object to add
-+         */
-+        public void add(E obj) {
-+            super.add(obj);
-+            // add on iterator does not return the added element
-+            next = next.next;
-+        }
-+
-+        /**
-+         * Gets the index of the next element to be returned.
-+         *
-+         * @return the next index
-+         */
-+        public int nextIndex() {
-+            if (nextIndexValid == false) {
-+                if (next == parent.header) {
-+                    nextIndex = parent.size();
-+                } else {
-+                    int pos = 0;
-+                    Node temp = parent.header.next;
-+                    while (temp != next) {
-+                        pos++;
-+                        temp = temp.next;
-+                    }
-+                    nextIndex = pos;
-+                }
-+                nextIndexValid = true;
-+            }
-+            return nextIndex;
-+        }
-+
-+        /**
-+         * Handle event from the list when a node has changed.
-+         *
-+         * @param node the node that changed
-+         */
-+        protected void nodeChanged(Node<E> node) {
-+            // do nothing
-+        }
-+
-+        /**
-+         * Handle event from the list when a node has been removed.
-+         *
-+         * @param node the node that was removed
-+         */
-+        protected void nodeRemoved(Node<E> node) {
-+            if (node == next) {
-+                next = node.next;
-+            } else if (node == current) {
-+                current = null;
-+                nextIndex--;
-+            } else {
-+                nextIndexValid = false;
-+            }
-+        }
-+
-+        /**
-+         * Handle event from the list when a node has been added.
-+         *
-+         * @param node the node that was added
-+         */
-+        protected void nodeInserted(Node<E> node) {
-+            if (node.previous == current) {
-+                next = node;
-+            } else if (next.previous == node) {
-+                next = node;
-+            } else {
-+                nextIndexValid = false;
-+            }
-+        }
-+
-+        /**
-+         * Override superclass modCount check, and replace it with our valid flag.
-+         */
-+        protected void checkModCount() {
-+            if (!valid) {
-+                throw new ConcurrentModificationException("Cursor closed");
-+            }
-+        }
-+
-+        /**
-+         * Mark this cursor as no longer being needed. Any resources
-+         * associated with this cursor are immediately released.
-+         * In previous versions of this class, it was mandatory to close
-+         * all cursor objects to avoid memory leaks. It is <i>no longer</i>
-+         * necessary to call this close method; an instance of this class
-+         * can now be treated exactly like a normal iterator.
-+         */
-+        public void close() {
-+            if (valid) {
-+                ((CursorableLinkedList) parent).unregisterCursor(this);
-+                valid = false;
-+            }
-+        }
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/FastArrayList.java
-@@ -0,0 +1,1286 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import java.util.*;
-+
-+/**
-+ * <p>A customized implementation of <code>java.util.ArrayList</code> designed
-+ * to operate in a multithreaded environment where the large majority of
-+ * method calls are read-only, instead of structural changes.  When operating
-+ * in "fast" mode, read calls are non-synchronized and write calls perform the
-+ * following steps:</p>
-+ * <ul>
-+ * <li>Clone the existing collection
-+ * <li>Perform the modification on the clone
-+ * <li>Replace the existing collection with the (modified) clone
-+ * </ul>
-+ * <p>When first created, objects of this class default to "slow" mode, where
-+ * all accesses of any type are synchronized but no cloning takes place.  This
-+ * is appropriate for initially populating the collection, followed by a switch
-+ * to "fast" mode (by calling <code>setFast(true)</code>) after initialization
-+ * is complete.</p>
-+ * <p/>
-+ * <p><strong>NOTE</strong>: If you are creating and accessing an
-+ * <code>ArrayList</code> only within a single thread, you should use
-+ * <code>java.util.ArrayList</code> directly (with no synchronization), for
-+ * maximum performance.</p>
-+ * <p/>
-+ * <p><strong>NOTE</strong>: <i>This class is not cross-platform.
-+ * Using it may cause unexpected failures on some architectures.</i>
-+ * It suffers from the same problems as the double-checked locking idiom.
-+ * In particular, the instruction that clones the internal collection and the
-+ * instruction that sets the internal reference to the clone can be executed
-+ * or perceived out-of-order.  This means that any read operation might fail
-+ * unexpectedly, as it may be reading the state of the internal collection
-+ * before the internal collection is fully formed.
-+ * For more information on the double-checked locking idiom, see the
-+ * <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">
-+ * Double-Checked Locking Idiom Is Broken Declaration</a>.</p>
-+ *
-+ * @author Matt Hall, John Watkinson, Craig R. McClanahan
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 1.0
-+ */
-+public class FastArrayList <E> extends ArrayList<E> {
-+
-+
-+    // ----------------------------------------------------------- Constructors
-+
-+
-+    /**
-+     * Construct a an empty list.
-+     */
-+    public FastArrayList() {
-+
-+        super();
-+        this.list = new ArrayList<E>();
-+
-+    }
-+
-+
-+    /**
-+     * Construct an empty list with the specified capacity.
-+     *
-+     * @param capacity The initial capacity of the empty list
-+     */
-+    public FastArrayList(int capacity) {
-+
-+        super();
-+        this.list = new ArrayList<E>(capacity);
-+
-+    }
-+
-+
-+    /**
-+     * Construct a list containing the elements of the specified collection,
-+     * in the order they are returned by the collection's iterator.
-+     *
-+     * @param collection The collection whose elements initialize the contents
-+     *                   of this list
-+     */
-+    public FastArrayList(Collection<E> collection) {
-+
-+        super();
-+        this.list = new ArrayList<E>(collection);
-+
-+    }
-+
-+
-+    // ----------------------------------------------------- Instance Variables
-+
-+
-+    /**
-+     * The underlying list we are managing.
-+     */
-+    protected ArrayList<E> list = null;
-+
-+
-+    // ------------------------------------------------------------- Properties
-+
-+
-+    /**
-+     * Are we operating in "fast" mode?
-+     */
-+    protected boolean fast = false;
-+
-+
-+    /**
-+     * Returns true if this list is operating in fast mode.
-+     *
-+     * @return true if this list is operating in fast mode
-+     */
-+    public boolean getFast() {
-+        return (this.fast);
-+    }
-+
-+    /**
-+     * Sets whether this list will operate in fast mode.
-+     *
-+     * @param fast true if the list should operate in fast mode
-+     */
-+    public void setFast(boolean fast) {
-+        this.fast = fast;
-+    }
-+
-+
-+    // --------------------------------------------------------- Public Methods
-+
-+
-+    /**
-+     * Appends the specified element to the end of this list.
-+     *
-+     * @param element The element to be appended
-+     */
-+    public boolean add(E element) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                boolean result = temp.add(element);
-+                list = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (list) {
-+                return (list.add(element));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Insert the specified element at the specified position in this list,
-+     * and shift all remaining elements up one position.
-+     *
-+     * @param index   Index at which to insert this element
-+     * @param element The element to be inserted
-+     * @throws IndexOutOfBoundsException if the index is out of range
-+     */
-+    public void add(int index, E element) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                temp.add(index, element);
-+                list = temp;
-+            }
-+        } else {
-+            synchronized (list) {
-+                list.add(index, element);
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Append all of the elements in the specified Collection to the end
-+     * of this list, in the order that they are returned by the specified
-+     * Collection's Iterator.
-+     *
-+     * @param collection The collection to be appended
-+     */
-+    public boolean addAll(Collection<? extends E> collection) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                boolean result = temp.addAll(collection);
-+                list = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (list) {
-+                return (list.addAll(collection));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Insert all of the elements in the specified Collection at the specified
-+     * position in this list, and shift any previous elements upwards as
-+     * needed.
-+     *
-+     * @param index      Index at which insertion takes place
-+     * @param collection The collection to be added
-+     * @throws IndexOutOfBoundsException if the index is out of range
-+     */
-+    public boolean addAll(int index, Collection<? extends E> collection) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                boolean result = temp.addAll(index, collection);
-+                list = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (list) {
-+                return (list.addAll(index, collection));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Remove all of the elements from this list.  The list will be empty
-+     * after this call returns.
-+     *
-+     * @throws UnsupportedOperationException if <code>clear()</code>
-+     *                                       is not supported by this list
-+     */
-+    public void clear() {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                temp.clear();
-+                list = temp;
-+            }
-+        } else {
-+            synchronized (list) {
-+                list.clear();
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return a shallow copy of this <code>FastArrayList</code> instance.
-+     * The elements themselves are not copied.
-+     */
-+    public Object clone() {
-+
-+        FastArrayList<E> results = null;
-+        if (fast) {
-+            results = new FastArrayList<E>(list);
-+        } else {
-+            synchronized (list) {
-+                results = new FastArrayList<E>(list);
-+            }
-+        }
-+        results.setFast(getFast());
-+        return (results);
-+
-+    }
-+
-+
-+    /**
-+     * Return <code>true</code> if this list contains the specified element.
-+     *
-+     * @param element The element to test for
-+     */
-+    public boolean contains(Object element) {
-+
-+        if (fast) {
-+            return (list.contains(element));
-+        } else {
-+            synchronized (list) {
-+                return (list.contains(element));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return <code>true</code> if this list contains all of the elements
-+     * in the specified Collection.
-+     *
-+     * @param collection Collection whose elements are to be checked
-+     */
-+    public boolean containsAll(Collection<?> collection) {
-+
-+        if (fast) {
-+            return (list.containsAll(collection));
-+        } else {
-+            synchronized (list) {
-+                return (list.containsAll(collection));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Increase the capacity of this <code>ArrayList</code> instance, if
-+     * necessary, to ensure that it can hold at least the number of elements
-+     * specified by the minimum capacity argument.
-+     *
-+     * @param capacity The new minimum capacity
-+     */
-+    public void ensureCapacity(int capacity) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                temp.ensureCapacity(capacity);
-+                list = temp;
-+            }
-+        } else {
-+            synchronized (list) {
-+                list.ensureCapacity(capacity);
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Compare the specified object with this list for equality.  This
-+     * implementation uses exactly the code that is used to define the
-+     * list equals function in the documentation for the
-+     * <code>List.equals</code> method.
-+     *
-+     * @param o Object to be compared to this list
-+     */
-+    public boolean equals(Object o) {
-+
-+        // Simple tests that require no synchronization
-+        if (o == this)
-+            return (true);
-+        else if (!(o instanceof List))
-+            return (false);
-+        List lo = (List) o;
-+
-+        // Compare the sets of elements for equality
-+        if (fast) {
-+            ListIterator li1 = list.listIterator();
-+            ListIterator li2 = lo.listIterator();
-+            while (li1.hasNext() && li2.hasNext()) {
-+                Object o1 = li1.next();
-+                Object o2 = li2.next();
-+                if (!(o1 == null ? o2 == null : o1.equals(o2)))
-+                    return (false);
-+            }
-+            return (!(li1.hasNext() || li2.hasNext()));
-+        } else {
-+            synchronized (list) {
-+                ListIterator li1 = list.listIterator();
-+                ListIterator li2 = lo.listIterator();
-+                while (li1.hasNext() && li2.hasNext()) {
-+                    Object o1 = li1.next();
-+                    Object o2 = li2.next();
-+                    if (!(o1 == null ? o2 == null : o1.equals(o2)))
-+                        return (false);
-+                }
-+                return (!(li1.hasNext() || li2.hasNext()));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return the element at the specified position in the list.
-+     *
-+     * @param index The index of the element to return
-+     * @throws IndexOutOfBoundsException if the index is out of range
-+     */
-+    public E get(int index) {
-+
-+        if (fast) {
-+            return (list.get(index));
-+        } else {
-+            synchronized (list) {
-+                return (list.get(index));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return the hash code value for this list.  This implementation uses
-+     * exactly the code that is used to define the list hash function in the
-+     * documentation for the <code>List.hashCode</code> method.
-+     */
-+    public int hashCode() {
-+
-+        if (fast) {
-+            int hashCode = 1;
-+            java.util.Iterator i = list.iterator();
-+            while (i.hasNext()) {
-+                Object o = i.next();
-+                hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
-+            }
-+            return (hashCode);
-+        } else {
-+            synchronized (list) {
-+                int hashCode = 1;
-+                java.util.Iterator i = list.iterator();
-+                while (i.hasNext()) {
-+                    Object o = i.next();
-+                    hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
-+                }
-+                return (hashCode);
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Search for the first occurrence of the given argument, testing
-+     * for equality using the <code>equals()</code> method, and return
-+     * the corresponding index, or -1 if the object is not found.
-+     *
-+     * @param element The element to search for
-+     */
-+    public int indexOf(Object element) {
-+
-+        if (fast) {
-+            return (list.indexOf(element));
-+        } else {
-+            synchronized (list) {
-+                return (list.indexOf(element));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Test if this list has no elements.
-+     */
-+    public boolean isEmpty() {
-+
-+        if (fast) {
-+            return (list.isEmpty());
-+        } else {
-+            synchronized (list) {
-+                return (list.isEmpty());
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return an iterator over the elements in this list in proper sequence.
-+     * <br><br>
-+     * <strong>IMPLEMENTATION NOTE</strong> - If the list is operating in fast
-+     * mode, an Iterator is returned, and a structural modification to the
-+     * list is made, then the Iterator will continue over the previous contents
-+     * of the list (at the time that the Iterator was created), rather than
-+     * failing due to concurrent modifications.
-+     */
-+    public Iterator<E> iterator() {
-+        if (fast) {
-+            return new ListIter(0);
-+        } else {
-+            return list.iterator();
-+        }
-+    }
-+
-+
-+    /**
-+     * Search for the last occurrence of the given argument, testing
-+     * for equality using the <code>equals()</code> method, and return
-+     * the corresponding index, or -1 if the object is not found.
-+     *
-+     * @param element The element to search for
-+     */
-+    public int lastIndexOf(Object element) {
-+
-+        if (fast) {
-+            return (list.lastIndexOf(element));
-+        } else {
-+            synchronized (list) {
-+                return (list.lastIndexOf(element));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return an iterator of the elements of this list, in proper sequence.
-+     * See the implementation note on <code>iterator()</code>.
-+     */
-+    public ListIterator<E> listIterator() {
-+        if (fast) {
-+            return new ListIter(0);
-+        } else {
-+            return list.listIterator();
-+        }
-+    }
-+
-+
-+    /**
-+     * Return an iterator of the elements of this list, in proper sequence,
-+     * starting at the specified position.
-+     * See the implementation note on <code>iterator()</code>.
-+     *
-+     * @param index The starting position of the iterator to return
-+     * @throws IndexOutOfBoundsException if the index is out of range
-+     */
-+    public ListIterator<E> listIterator(int index) {
-+        if (fast) {
-+            return new ListIter(index);
-+        } else {
-+            return list.listIterator(index);
-+        }
-+    }
-+
-+
-+    /**
-+     * Remove the element at the specified position in the list, and shift
-+     * any subsequent elements down one position.
-+     *
-+     * @param index Index of the element to be removed
-+     * @throws IndexOutOfBoundsException if the index is out of range
-+     */
-+    public E remove(int index) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                E result = temp.remove(index);
-+                list = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (list) {
-+                return (list.remove(index));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Remove the first occurrence of the specified element from the list,
-+     * and shift any subsequent elements down one position.
-+     *
-+     * @param element Element to be removed
-+     */
-+    public boolean remove(Object element) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList temp = (ArrayList) list.clone();
-+                boolean result = temp.remove(element);
-+                list = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (list) {
-+                return (list.remove(element));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Remove from this collection all of its elements that are contained
-+     * in the specified collection.
-+     *
-+     * @param collection Collection containing elements to be removed
-+     * @throws UnsupportedOperationException if this optional operation
-+     *                                       is not supported by this list
-+     */
-+    public boolean removeAll(Collection<?> collection) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList temp = (ArrayList) list.clone();
-+                boolean result = temp.removeAll(collection);
-+                list = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (list) {
-+                return (list.removeAll(collection));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Remove from this collection all of its elements except those that are
-+     * contained in the specified collection.
-+     *
-+     * @param collection Collection containing elements to be retained
-+     * @throws UnsupportedOperationException if this optional operation
-+     *                                       is not supported by this list
-+     */
-+    public boolean retainAll(Collection<?> collection) {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList temp = (ArrayList) list.clone();
-+                boolean result = temp.retainAll(collection);
-+                list = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (list) {
-+                return (list.retainAll(collection));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Replace the element at the specified position in this list with
-+     * the specified element.  Returns the previous object at that position.
-+     * <br><br>
-+     * <strong>IMPLEMENTATION NOTE</strong> - This operation is specifically
-+     * documented to not be a structural change, so it is safe to be performed
-+     * without cloning.
-+     *
-+     * @param index   Index of the element to replace
-+     * @param element The new element to be stored
-+     * @throws IndexOutOfBoundsException if the index is out of range
-+     */
-+    public E set(int index, E element) {
-+
-+        if (fast) {
-+            return (list.set(index, element));
-+        } else {
-+            synchronized (list) {
-+                return (list.set(index, element));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return the number of elements in this list.
-+     */
-+    public int size() {
-+
-+        if (fast) {
-+            return (list.size());
-+        } else {
-+            synchronized (list) {
-+                return (list.size());
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return a view of the portion of this list between fromIndex
-+     * (inclusive) and toIndex (exclusive).  The returned list is backed
-+     * by this list, so non-structural changes in the returned list are
-+     * reflected in this list.  The returned list supports
-+     * all of the optional list operations supported by this list.
-+     *
-+     * @param fromIndex The starting index of the sublist view
-+     * @param toIndex   The index after the end of the sublist view
-+     * @throws IndexOutOfBoundsException if an index is out of range
-+     */
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        if (fast) {
-+            return new SubList(fromIndex, toIndex);
-+        } else {
-+            return list.subList(fromIndex, toIndex);
-+        }
-+    }
-+
-+
-+    /**
-+     * Return an array containing all of the elements in this list in the
-+     * correct order.
-+     */
-+    public Object[] toArray() {
-+
-+        if (fast) {
-+            return (list.toArray());
-+        } else {
-+            synchronized (list) {
-+                return (list.toArray());
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return an array containing all of the elements in this list in the
-+     * correct order.  The runtime type of the returned array is that of
-+     * the specified array.  If the list fits in the specified array, it is
-+     * returned therein.  Otherwise, a new array is allocated with the
-+     * runtime type of the specified array, and the size of this list.
-+     *
-+     * @param array Array defining the element type of the returned list
-+     * @throws ArrayStoreException if the runtime type of <code>array</code>
-+     *                             is not a supertype of the runtime type of every element in this list
-+     */
-+    public <T> T[] toArray(T[] array) {
-+
-+        if (fast) {
-+            return (list.toArray(array));
-+        } else {
-+            synchronized (list) {
-+                return (list.toArray(array));
-+            }
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Return a String representation of this object.
-+     */
-+    public String toString() {
-+
-+        StringBuffer sb = new StringBuffer("FastArrayList[");
-+        sb.append(list.toString());
-+        sb.append("]");
-+        return (sb.toString());
-+
-+    }
-+
-+
-+    /**
-+     * Trim the capacity of this <code>ArrayList</code> instance to be the
-+     * list's current size.  An application can use this operation to minimize
-+     * the storage of an <code>ArrayList</code> instance.
-+     */
-+    public void trimToSize() {
-+
-+        if (fast) {
-+            synchronized (this) {
-+                ArrayList temp = (ArrayList) list.clone();
-+                temp.trimToSize();
-+                list = temp;
-+            }
-+        } else {
-+            synchronized (list) {
-+                list.trimToSize();
-+            }
-+        }
-+
-+    }
-+
-+
-+    private class SubList implements List<E> {
-+
-+        private int first;
-+        private int last;
-+        private List<E> expected;
-+
-+
-+        public SubList(int first, int last) {
-+            this.first = first;
-+            this.last = last;
-+            this.expected = list;
-+        }
-+
-+        private List<E> get(List<E> l) {
-+            if (list != expected) {
-+                throw new ConcurrentModificationException();
-+            }
-+            return l.subList(first, last);
-+        }
-+
-+        public void clear() {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList<E> temp = (ArrayList<E>) list.clone();
-+                    get(temp).clear();
-+                    last = first;
-+                    list = temp;
-+                    expected = temp;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    get(expected).clear();
-+                }
-+            }
-+        }
-+
-+        public boolean remove(Object o) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    boolean r = get(temp).remove(o);
-+                    if (r) last--;
-+                    list = temp;
-+                    expected = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).remove(o);
-+                }
-+            }
-+        }
-+
-+        public boolean removeAll(Collection<?> o) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    List sub = get(temp);
-+                    boolean r = sub.removeAll(o);
-+                    if (r) last = first + sub.size();
-+                    list = temp;
-+                    expected = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).removeAll(o);
-+                }
-+            }
-+        }
-+
-+        public boolean retainAll(Collection<?> o) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    List sub = get(temp);
-+                    boolean r = sub.retainAll(o);
-+                    if (r) last = first + sub.size();
-+                    list = temp;
-+                    expected = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).retainAll(o);
-+                }
-+            }
-+        }
-+
-+        public int size() {
-+            if (fast) {
-+                return get(expected).size();
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).size();
-+                }
-+            }
-+        }
-+
-+
-+        public boolean isEmpty() {
-+            if (fast) {
-+                return get(expected).isEmpty();
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).isEmpty();
-+                }
-+            }
-+        }
-+
-+        public boolean contains(Object o) {
-+            if (fast) {
-+                return get(expected).contains(o);
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).contains(o);
-+                }
-+            }
-+        }
-+
-+        public boolean containsAll(Collection<?> o) {
-+            if (fast) {
-+                return get(expected).containsAll(o);
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).containsAll(o);
-+                }
-+            }
-+        }
-+
-+        public <T> T[] toArray(T[] o) {
-+            if (fast) {
-+                return get(expected).toArray(o);
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).toArray(o);
-+                }
-+            }
-+        }
-+
-+        public Object[] toArray() {
-+            if (fast) {
-+                return get(expected).toArray();
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).toArray();
-+                }
-+            }
-+        }
-+
-+
-+        public boolean equals(Object o) {
-+            if (o == this) return true;
-+            if (fast) {
-+                return get(expected).equals(o);
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).equals(o);
-+                }
-+            }
-+        }
-+
-+        public int hashCode() {
-+            if (fast) {
-+                return get(expected).hashCode();
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).hashCode();
-+                }
-+            }
-+        }
-+
-+        public boolean add(E o) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    boolean r = get(temp).add(o);
-+                    if (r) last++;
-+                    list = temp;
-+                    expected = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).add(o);
-+                }
-+            }
-+        }
-+
-+        public boolean addAll(Collection<? extends E> o) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    boolean r = get(temp).addAll(o);
-+                    if (r) last += o.size();
-+                    list = temp;
-+                    expected = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).addAll(o);
-+                }
-+            }
-+        }
-+
-+        public void add(int i, E o) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    get(temp).add(i, o);
-+                    last++;
-+                    list = temp;
-+                    expected = temp;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    get(expected).add(i, o);
-+                }
-+            }
-+        }
-+
-+        public boolean addAll(int i, Collection<? extends E> o) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    boolean r = get(temp).addAll(i, o);
-+                    list = temp;
-+                    if (r) last += o.size();
-+                    expected = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).addAll(i, o);
-+                }
-+            }
-+        }
-+
-+        public E remove(int i) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    E o = get(temp).remove(i);
-+                    last--;
-+                    list = temp;
-+                    expected = temp;
-+                    return o;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).remove(i);
-+                }
-+            }
-+        }
-+
-+        public E set(int i, E a) {
-+            if (fast) {
-+                synchronized (FastArrayList.this) {
-+                    ArrayList temp = (ArrayList) list.clone();
-+                    E o = get(temp).set(i, a);
-+                    list = temp;
-+                    expected = temp;
-+                    return o;
-+                }
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).set(i, a);
-+                }
-+            }
-+        }
-+
-+
-+        public Iterator<E> iterator() {
-+            return new SubListIter(0);
-+        }
-+
-+        public ListIterator<E> listIterator() {
-+            return new SubListIter(0);
-+        }
-+
-+        public ListIterator<E> listIterator(int i) {
-+            return new SubListIter(i);
-+        }
-+
-+
-+        public E get(int i) {
-+            if (fast) {
-+                return get(expected).get(i);
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).get(i);
-+                }
-+            }
-+        }
-+
-+        public int indexOf(Object o) {
-+            if (fast) {
-+                return get(expected).indexOf(o);
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).indexOf(o);
-+                }
-+            }
-+        }
-+
-+
-+        public int lastIndexOf(Object o) {
-+            if (fast) {
-+                return get(expected).lastIndexOf(o);
-+            } else {
-+                synchronized (list) {
-+                    return get(expected).lastIndexOf(o);
-+                }
-+            }
-+        }
-+
-+
-+        public List<E> subList(int f, int l) {
-+            if (list != expected) {
-+                throw new ConcurrentModificationException();
-+            }
-+            return new SubList(first + f, f + l);
-+        }
-+
-+
-+        private class SubListIter implements ListIterator<E> {
-+
-+            private List<E> expected;
-+            private ListIterator<E> iter;
-+            private int lastReturnedIndex = -1;
-+
-+
-+            public SubListIter(int i) {
-+                this.expected = list;
-+                this.iter = SubList.this.get(expected).listIterator(i);
-+            }
-+
-+            private void checkMod() {
-+                if (list != expected) {
-+                    throw new ConcurrentModificationException();
-+                }
-+            }
-+
-+            List<E> get() {
-+                return SubList.this.get(expected);
-+            }
-+
-+            public boolean hasNext() {
-+                checkMod();
-+                return iter.hasNext();
-+            }
-+
-+            public E next() {
-+                checkMod();
-+                lastReturnedIndex = iter.nextIndex();
-+                return iter.next();
-+            }
-+
-+            public boolean hasPrevious() {
-+                checkMod();
-+                return iter.hasPrevious();
-+            }
-+
-+            public E previous() {
-+                checkMod();
-+                lastReturnedIndex = iter.previousIndex();
-+                return iter.previous();
-+            }
-+
-+            public int previousIndex() {
-+                checkMod();
-+                return iter.previousIndex();
-+            }
-+
-+            public int nextIndex() {
-+                checkMod();
-+                return iter.nextIndex();
-+            }
-+
-+            public void remove() {
-+                checkMod();
-+                if (lastReturnedIndex < 0) {
-+                    throw new IllegalStateException();
-+                }
-+                get().remove(lastReturnedIndex);
-+                last--;
-+                expected = list;
-+                iter = get().listIterator(previousIndex());
-+                lastReturnedIndex = -1;
-+            }
-+
-+            public void set(E o) {
-+                checkMod();
-+                if (lastReturnedIndex < 0) {
-+                    throw new IllegalStateException();
-+                }
-+                get().set(lastReturnedIndex, o);
-+                expected = list;
-+                iter = get().listIterator(previousIndex() + 1);
-+            }
-+
-+            public void add(E o) {
-+                checkMod();
-+                int i = nextIndex();
-+                get().add(i, o);
-+                last++;
-+                iter = get().listIterator(i + 1);
-+                lastReturnedIndex = 1;
-+            }
-+
-+        }
-+
-+
-+    }
-+
-+
-+    private class ListIter implements ListIterator<E> {
-+
-+        private List<E> expected;
-+        private ListIterator<E> iter;
-+        private int lastReturnedIndex = -1;
-+
-+
-+        public ListIter(int i) {
-+            this.expected = list;
-+            this.iter = get().listIterator(i);
-+        }
-+
-+        private void checkMod() {
-+            if (list != expected) {
-+                throw new ConcurrentModificationException();
-+            }
-+        }
-+
-+        List get() {
-+            return expected;
-+        }
-+
-+        public boolean hasNext() {
-+            checkMod();
-+            return iter.hasNext();
-+        }
-+
-+        public E next() {
-+            checkMod();
-+            lastReturnedIndex = iter.nextIndex();
-+            return iter.next();
-+        }
-+
-+        public boolean hasPrevious() {
-+            checkMod();
-+            return iter.hasPrevious();
-+        }
-+
-+        public E previous() {
-+            checkMod();
-+            lastReturnedIndex = iter.previousIndex();
-+            return iter.previous();
-+        }
-+
-+        public int previousIndex() {
-+            checkMod();
-+            return iter.previousIndex();
-+        }
-+
-+        public int nextIndex() {
-+            checkMod();
-+            return iter.nextIndex();
-+        }
-+
-+        public void remove() {
-+            checkMod();
-+            if (lastReturnedIndex < 0) {
-+                throw new IllegalStateException();
-+            }
-+            get().remove(lastReturnedIndex);
-+            expected = list;
-+            iter = get().listIterator(previousIndex());
-+            lastReturnedIndex = -1;
-+        }
-+
-+        public void set(E o) {
-+            checkMod();
-+            if (lastReturnedIndex < 0) {
-+                throw new IllegalStateException();
-+            }
-+            get().set(lastReturnedIndex, o);
-+            expected = list;
-+            iter = get().listIterator(previousIndex() + 1);
-+        }
-+
-+        public void add(E o) {
-+            checkMod();
-+            int i = nextIndex();
-+            get().add(i, o);
-+            iter = get().listIterator(i + 1);
-+            lastReturnedIndex = -1;
-+        }
-+
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/FixedSizeList.java
-@@ -0,0 +1,164 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.BoundedCollection;
-+import org.apache.commons.collections15.iterators.AbstractListIteratorDecorator;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.List;
-+import java.util.ListIterator;
-+
-+/**
-+ * Decorates another <code>List</code> to fix the size preventing add/remove.
-+ * <p/>
-+ * The add, remove, clear and retain operations are unsupported.
-+ * The set method is allowed (as it doesn't change the list size).
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class FixedSizeList <E> extends AbstractSerializableListDecorator<E> implements BoundedCollection<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -2218010673611160319L;
-+
-+    /**
-+     * Factory method to create a fixed size list.
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    public static <E> List<E> decorate(List<E> list) {
-+        return new FixedSizeList<E>(list);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    protected FixedSizeList(List<E> list) {
-+        super(list);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public void add(int index, E object) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public E get(int index) {
-+        return getList().get(index);
-+    }
-+
-+    public int indexOf(Object object) {
-+        return getList().indexOf(object);
-+    }
-+
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public int lastIndexOf(Object object) {
-+        return getList().lastIndexOf(object);
-+    }
-+
-+    public ListIterator<E> listIterator() {
-+        return new FixedSizeListIterator<E>(getList().listIterator(0));
-+    }
-+
-+    public ListIterator<E> listIterator(int index) {
-+        return new FixedSizeListIterator<E>(getList().listIterator(index));
-+    }
-+
-+    public E remove(int index) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException("List is fixed size");
-+    }
-+
-+    public E set(int index, E object) {
-+        return getList().set(index, object);
-+    }
-+
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        List<E> sub = getList().subList(fromIndex, toIndex);
-+        return new FixedSizeList<E>(sub);
-+    }
-+
-+    /**
-+     * List iterator that only permits changes via set()
-+     */
-+    static class FixedSizeListIterator <E> extends AbstractListIteratorDecorator<E> {
-+        protected FixedSizeListIterator(ListIterator<E> iterator) {
-+            super(iterator);
-+        }
-+
-+        public void remove() {
-+            throw new UnsupportedOperationException("List is fixed size");
-+        }
-+
-+        public void add(E object) {
-+            throw new UnsupportedOperationException("List is fixed size");
-+        }
-+    }
-+
-+    public boolean isFull() {
-+        return true;
-+    }
-+
-+    public int maxSize() {
-+        return size();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/LazyList.java
-@@ -0,0 +1,140 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.Factory;
-+
-+import java.util.List;
-+
-+/**
-+ * Decorates another <code>List</code> to create objects in the list on demand.
-+ * <p/>
-+ * When the {@link #get(int)} method is called with an index greater than
-+ * the size of the list, the list will automatically grow in size and return
-+ * a new object from the specified factory. The gaps will be filled by null.
-+ * If a get method call encounters a null, it will be replaced with a new
-+ * object from the factory. Thus this list is unsuitable for storing null
-+ * objects.
-+ * <p/>
-+ * For instance:
-+ * <p/>
-+ * <pre>
-+ * Factory factory = new Factory() {
-+ *     public Object create() {
-+ *         return new Date();
-+ *     }
-+ * }
-+ * List lazy = LazyList.decorate(new ArrayList(), factory);
-+ * Object obj = lazy.get(3);
-+ * </pre>
-+ * <p/>
-+ * After the above code is executed, <code>obj</code> will contain
-+ * a new <code>Date</code> instance.  Furthermore, that <code>Date</code>
-+ * instance is the fourth element in the list.  The first, second,
-+ * and third element are all set to <code>null</code>.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Arron Bates
-+ * @author Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class LazyList <E> extends AbstractSerializableListDecorator<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -1708388017160694542L;
-+
-+    /**
-+     * The factory to use to lazily instantiate the objects
-+     */
-+    protected final Factory<? extends E> factory;
-+
-+    /**
-+     * Factory method to create a lazily instantiating list.
-+     *
-+     * @param list    the list to decorate, must not be null
-+     * @param factory the factory to use for creation, must not be null
-+     * @throws IllegalArgumentException if list or factory is null
-+     */
-+    public static <E> List<E> decorate(List<E> list, Factory<? extends E> factory) {
-+        return new LazyList<E>(list, factory);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param list    the list to decorate, must not be null
-+     * @param factory the factory to use for creation, must not be null
-+     * @throws IllegalArgumentException if list or factory is null
-+     */
-+    protected LazyList(List<E> list, Factory<? extends E> factory) {
-+        super(list);
-+        if (factory == null) {
-+            throw new IllegalArgumentException("Factory must not be null");
-+        }
-+        this.factory = factory;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Decorate the get method to perform the lazy behaviour.
-+     * <p/>
-+     * If the requested index is greater than the current size, the list will
-+     * grow to the new size and a new object will be returned from the factory.
-+     * Indexes in-between the old size and the requested size are left with a
-+     * placeholder that is replaced with a factory object when requested.
-+     *
-+     * @param index the index to retrieve
-+     */
-+    public E get(int index) {
-+        int size = getList().size();
-+        if (index < size) {
-+            // within bounds, get the object
-+            E object = getList().get(index);
-+            if (object == null) {
-+                // item is a place holder, create new one, set and return
-+                object = factory.create();
-+                getList().set(index, object);
-+                return object;
-+            } else {
-+                // good and ready to go
-+                return object;
-+            }
-+        } else {
-+            // we have to grow the list
-+            for (int i = size; i < index; i++) {
-+                getList().add(null);
-+            }
-+            // create our last object, set and return
-+            E object = factory.create();
-+            getList().add(object);
-+            return object;
-+        }
-+    }
-+
-+
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        List<E> sub = getList().subList(fromIndex, toIndex);
-+        return new LazyList<E>(sub, factory);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/NodeCachingLinkedList.java
-@@ -0,0 +1,247 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+
-+/**
-+ * A <code>List</code> implementation that stores a cache of internal Node objects
-+ * in an effort to reduce wasteful object creation.
-+ * <p/>
-+ * A linked list creates one Node for each item of data added. This can result in
-+ * a lot of object creation and garbage collection. This implementation seeks to
-+ * avoid that by maintaining a store of cached nodes.
-+ * <p/>
-+ * This implementation is suitable for long-lived lists where both add and remove
-+ * are used. Short-lived lists, or lists which only grow will have worse performance
-+ * using this class.
-+ * <p/>
-+ * <b>Note that this implementation is not synchronized.</b>
-+ *
-+ * @author Matt Hall, John Watkinson, Jeff Varszegi
-+ * @author Rich Dougherty
-+ * @author Phil Steitz
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class NodeCachingLinkedList <E> extends AbstractLinkedList<E> implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    static final long serialVersionUID = 6897789178562232073L;
-+
-+    /**
-+     * The default value for {@link #maximumCacheSize}.
-+     */
-+    protected static final int DEFAULT_MAXIMUM_CACHE_SIZE = 20;
-+
-+    /**
-+     * The first cached node, or <code>null</code> if no nodes are cached.
-+     * Cached nodes are stored in a singly-linked list with
-+     * <code>next</code> pointing to the next element.
-+     */
-+    protected transient Node<E> firstCachedNode;
-+
-+    /**
-+     * The size of the cache.
-+     */
-+    protected transient int cacheSize;
-+
-+    /**
-+     * The maximum size of the cache.
-+     */
-+    protected int maximumCacheSize;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that creates.
-+     */
-+    public NodeCachingLinkedList() {
-+        this(DEFAULT_MAXIMUM_CACHE_SIZE);
-+    }
-+
-+    /**
-+     * Constructor that copies the specified collection
-+     *
-+     * @param coll the collection to copy
-+     */
-+    public NodeCachingLinkedList(Collection<E> coll) {
-+        super(coll);
-+        this.maximumCacheSize = DEFAULT_MAXIMUM_CACHE_SIZE;
-+    }
-+
-+    /**
-+     * Constructor that species the maximum cache size.
-+     *
-+     * @param maximumCacheSize the maximum cache size
-+     */
-+    public NodeCachingLinkedList(int maximumCacheSize) {
-+        super();
-+        this.maximumCacheSize = maximumCacheSize;
-+        init();  // must call init() as use super();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the maximum size of the cache.
-+     *
-+     * @return the maximum cache size
-+     */
-+    protected int getMaximumCacheSize() {
-+        return maximumCacheSize;
-+    }
-+
-+    /**
-+     * Sets the maximum size of the cache.
-+     *
-+     * @param maximumCacheSize the new maximum cache size
-+     */
-+    protected void setMaximumCacheSize(int maximumCacheSize) {
-+        this.maximumCacheSize = maximumCacheSize;
-+        shrinkCacheToMaximumSize();
-+    }
-+
-+    /**
-+     * Reduce the size of the cache to the maximum, if necessary.
-+     */
-+    protected void shrinkCacheToMaximumSize() {
-+        // Rich Dougherty: This could be more efficient.
-+        while (cacheSize > maximumCacheSize) {
-+            getNodeFromCache();
-+        }
-+    }
-+
-+    /**
-+     * Gets a node from the cache. If a node is returned, then the value of
-+     * {@link #cacheSize} is decreased accordingly. The node that is returned
-+     * will have <code>null</code> values for next, previous and element.
-+     *
-+     * @return a node, or <code>null</code> if there are no nodes in the cache.
-+     */
-+    protected Node<E> getNodeFromCache() {
-+        if (cacheSize == 0) {
-+            return null;
-+        }
-+        Node<E> cachedNode = firstCachedNode;
-+        firstCachedNode = cachedNode.next;
-+        cachedNode.next = null; // This should be changed anyway, but defensively
-+        // set it to null.
-+        cacheSize--;
-+        return cachedNode;
-+    }
-+
-+    /**
-+     * Checks whether the cache is full.
-+     *
-+     * @return true if the cache is full
-+     */
-+    protected boolean isCacheFull() {
-+        return cacheSize >= maximumCacheSize;
-+    }
-+
-+    /**
-+     * Adds a node to the cache, if the cache isn't full.
-+     * The node's contents are cleared to so they can be garbage collected.
-+     *
-+     * @param node the node to add to the cache
-+     */
-+    protected void addNodeToCache(Node<E> node) {
-+        if (isCacheFull()) {
-+            // don't cache the node.
-+            return;
-+        }
-+        // clear the node's contents and add it to the cache.
-+        Node<E> nextCachedNode = firstCachedNode;
-+        node.previous = null;
-+        node.next = nextCachedNode;
-+        node.setValue(null);
-+        firstCachedNode = node;
-+        cacheSize++;
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Creates a new node, either by reusing one from the cache or creating
-+     * a new one.
-+     *
-+     * @param value value of the new node
-+     * @return the newly created node
-+     */
-+    protected Node<E> createNode(E value) {
-+        Node<E> cachedNode = getNodeFromCache();
-+        if (cachedNode == null) {
-+            return super.createNode(value);
-+        } else {
-+            cachedNode.setValue(value);
-+            return cachedNode;
-+        }
-+    }
-+
-+    /**
-+     * Removes the node from the list, storing it in the cache for reuse
-+     * if the cache is not yet full.
-+     *
-+     * @param node the node to remove
-+     */
-+    protected void removeNode(Node<E> node) {
-+        super.removeNode(node);
-+        addNodeToCache(node);
-+    }
-+
-+    /**
-+     * Removes all the nodes from the list, storing as many as required in the
-+     * cache for reuse.
-+     */
-+    protected void removeAllNodes() {
-+        // Add the removed nodes to the cache, then remove the rest.
-+        // We can add them to the cache before removing them, since
-+        // {@link AbstractLinkedList.removeAllNodes()} removes the
-+        // nodes by removing references directly from {@link #header}.
-+        int numberOfNodesToCache = Math.min(size, maximumCacheSize - cacheSize);
-+        Node<E> node = header.next;
-+        for (int currentIndex = 0; currentIndex < numberOfNodesToCache; currentIndex++) {
-+            Node<E> oldNode = node;
-+            node = node.next;
-+            addNodeToCache(oldNode);
-+        }
-+        super.removeAllNodes();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Serializes the data held in this object to the stream specified.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Deserializes the data held in this object to the stream specified.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/PredicatedList.java
-@@ -0,0 +1,161 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.collection.PredicatedCollection;
-+import org.apache.commons.collections15.iterators.AbstractListIteratorDecorator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.List;
-+import java.util.ListIterator;
-+
-+/**
-+ * Decorates another <code>List</code> to validate that all additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This list exists to provide validation for the decorated list.
-+ * It is normally created to decorate an empty list.
-+ * If an object cannot be added to the list, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null entries are added to the list.
-+ * <pre>List list = PredicatedList.decorate(new ArrayList(), NotNullPredicate.INSTANCE);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @author Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedList <E> extends PredicatedCollection<E> implements List<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -5722039223898659102L;
-+
-+    /**
-+     * Factory method to create a predicated (validating) list.
-+     * <p/>
-+     * If there are any elements already in the list being decorated, they
-+     * are validated.
-+     *
-+     * @param list      the list to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if list or predicate is null
-+     * @throws IllegalArgumentException if the list contains invalid elements
-+     */
-+    public static <E> List<E> decorate(List<E> list, Predicate<? super E> predicate) {
-+        return new PredicatedList<E>(list, predicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the list being decorated, they
-+     * are validated.
-+     *
-+     * @param list      the list to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if list or predicate is null
-+     * @throws IllegalArgumentException if the list contains invalid elements
-+     */
-+    protected PredicatedList(List<E> list, Predicate<? super E> predicate) {
-+        super(list, predicate);
-+    }
-+
-+    /**
-+     * Gets the list being decorated.
-+     *
-+     * @return the decorated list
-+     */
-+    protected List<E> getList() {
-+        return (List<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E get(int index) {
-+        return getList().get(index);
-+    }
-+
-+    public int indexOf(Object object) {
-+        return getList().indexOf(object);
-+    }
-+
-+    public int lastIndexOf(Object object) {
-+        return getList().lastIndexOf(object);
-+    }
-+
-+    public E remove(int index) {
-+        return getList().remove(index);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void add(int index, E object) {
-+        validate(object);
-+        getList().add(index, object);
-+    }
-+
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        for (Iterator<? extends E> it = coll.iterator(); it.hasNext();) {
-+            validate(it.next());
-+        }
-+        return getList().addAll(index, coll);
-+    }
-+
-+    public ListIterator<E> listIterator() {
-+        return listIterator(0);
-+    }
-+
-+    public ListIterator<E> listIterator(int i) {
-+        return new PredicatedListIterator(getList().listIterator(i));
-+    }
-+
-+    public E set(int index, E object) {
-+        validate(object);
-+        return getList().set(index, object);
-+    }
-+
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        List<E> sub = getList().subList(fromIndex, toIndex);
-+        return new PredicatedList<E>(sub, predicate);
-+    }
-+
-+    /**
-+     * Inner class Iterator for the PredicatedList
-+     */
-+    protected class PredicatedListIterator extends AbstractListIteratorDecorator<E> {
-+
-+        protected PredicatedListIterator(ListIterator<E> iterator) {
-+            super(iterator);
-+        }
-+
-+        public void add(E object) {
-+            validate(object);
-+            iterator.add(object);
-+        }
-+
-+        public void set(E object) {
-+            validate(object);
-+            iterator.set(object);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/SetUniqueList.java
-@@ -0,0 +1,332 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.iterators.AbstractIteratorDecorator;
-+import org.apache.commons.collections15.iterators.AbstractListIteratorDecorator;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.util.*;
-+
-+/**
-+ * Decorates a <code>List</code> to ensure that no duplicates are present
-+ * much like a <code>Set</code>.
-+ * <p/>
-+ * The <code>List</code> interface makes certain assumptions/requirements.
-+ * This implementation breaks these in certain ways, but this is merely the
-+ * result of rejecting duplicates.
-+ * Each violation is explained in the method, but it should not affect you.
-+ * <p/>
-+ * The {@link org.apache.commons.collections15.set.ListOrderedSet ListOrderedSet}
-+ * class provides an alternative approach, by wrapping an existing Set and
-+ * retaining insertion order in the iterator.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matthew Hawthorne
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SetUniqueList <E> extends AbstractSerializableListDecorator<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 7196982186153478694L;
-+
-+    /**
-+     * Internal Set to maintain uniqueness.
-+     */
-+    protected final Set<E> set;
-+
-+    /**
-+     * Factory method to create a SetList using the supplied list to retain order.
-+     * <p/>
-+     * If the list contains duplicates, these are removed (first indexed one kept).
-+     * A <code>HashSet</code> is used for the set behaviour.
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    public static <E> SetUniqueList<E> decorate(List<E> list) {
-+        if (list == null) {
-+            throw new IllegalArgumentException("List must not be null");
-+        }
-+        if (list.isEmpty()) {
-+            return new SetUniqueList<E>(list, new HashSet());
-+        } else {
-+            List temp = new ArrayList(list);
-+            list.clear();
-+            SetUniqueList<E> sl = new SetUniqueList<E>(list, new HashSet());
-+            sl.addAll(temp);
-+            return sl;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies) the List and specifies the set to use.
-+     * <p/>
-+     * The set and list must both be correctly initialised to the same elements.
-+     *
-+     * @param set  the set to decorate, must not be null
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if set or list is null
-+     */
-+    protected SetUniqueList(List<E> list, Set<E> set) {
-+        super(list);
-+        if (set == null) {
-+            throw new IllegalArgumentException("Set must not be null");
-+        }
-+        this.set = set;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an unmodifiable view as a Set.
-+     *
-+     * @return an unmodifiable set view
-+     */
-+    public Set<E> asSet() {
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Adds an element to the list if it is not already present.
-+     * <p/>
-+     * <i>(Violation)</i>
-+     * The <code>List</code> interface requires that this method returns
-+     * <code>true</code> always. However this class may return <code>false</code>
-+     * because of the <code>Set</code> behaviour.
-+     *
-+     * @param object the object to add
-+     * @return true if object was added
-+     */
-+    public boolean add(E object) {
-+        // gets initial size
-+        final int sizeBefore = size();
-+
-+        // adds element if unique
-+        add(size(), object);
-+
-+        // compares sizes to detect if collection changed
-+        return (sizeBefore != size());
-+    }
-+
-+    /**
-+     * Adds an element to a specific index in the list if it is not already present.
-+     * <p/>
-+     * <i>(Violation)</i>
-+     * The <code>List</code> interface makes the assumption that the element is
-+     * always inserted. This may not happen with this implementation.
-+     *
-+     * @param index  the index to insert at
-+     * @param object the object to add
-+     */
-+    public void add(int index, E object) {
-+        // adds element if it is not contained already
-+        if (set.contains(object) == false) {
-+            super.add(index, object);
-+            set.add(object);
-+        }
-+    }
-+
-+    /**
-+     * Adds an element to the end of the list if it is not already present.
-+     * <p/>
-+     * <i>(Violation)</i>
-+     * The <code>List</code> interface makes the assumption that the element is
-+     * always inserted. This may not happen with this implementation.
-+     *
-+     * @param coll the collection to add
-+     */
-+    public boolean addAll(Collection<? extends E> coll) {
-+        return addAll(size(), coll);
-+    }
-+
-+    /**
-+     * Adds a collection of objects to the end of the list avoiding duplicates.
-+     * <p/>
-+     * Only elements that are not already in this list will be added, and
-+     * duplicates from the specified collection will be ignored.
-+     * <p/>
-+     * <i>(Violation)</i>
-+     * The <code>List</code> interface makes the assumption that the elements
-+     * are always inserted. This may not happen with this implementation.
-+     *
-+     * @param index the index to insert at
-+     * @param coll  the collection to add in iterator order
-+     * @return true if this collection changed
-+     */
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        // gets initial size
-+        final int sizeBefore = size();
-+
-+        // adds all elements
-+        for (final Iterator it = coll.iterator(); it.hasNext();) {
-+            add((E) it.next());
-+        }
-+
-+        // compares sizes to detect if collection changed
-+        return sizeBefore != size();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Sets the value at the specified index avoiding duplicates.
-+     * <p/>
-+     * The object is set into the specified index.
-+     * Afterwards, any previous duplicate is removed
-+     * If the object is not already in the list then a normal set occurs.
-+     * If it is present, then the old version is removed and re-added at this index
-+     *
-+     * @param index  the index to insert at
-+     * @param object the object to set
-+     * @return the previous object
-+     */
-+    public E set(int index, E object) {
-+        int pos = indexOf(object);
-+        E result = super.set(index, object);
-+        if (pos == -1 || pos == index) {
-+            return result;
-+        }
-+        return remove(pos);
-+    }
-+
-+    public boolean remove(Object object) {
-+        boolean result = super.remove(object);
-+        set.remove(object);
-+        return result;
-+    }
-+
-+    public E remove(int index) {
-+        E result = super.remove(index);
-+        set.remove(result);
-+        return result;
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        boolean result = super.removeAll(coll);
-+        set.removeAll(coll);
-+        return result;
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        boolean result = super.retainAll(coll);
-+        set.retainAll(coll);
-+        return result;
-+    }
-+
-+    public void clear() {
-+        super.clear();
-+        set.clear();
-+    }
-+
-+    public boolean contains(Object object) {
-+        return set.contains(object);
-+    }
-+
-+    public boolean containsAll(Collection<?> coll) {
-+        return set.containsAll(coll);
-+    }
-+
-+    public Iterator<E> iterator() {
-+        return new SetListIterator(super.iterator(), set);
-+    }
-+
-+    public ListIterator<E> listIterator() {
-+        return new SetListListIterator(super.listIterator(), set);
-+    }
-+
-+    public ListIterator<E> listIterator(int index) {
-+        return new SetListListIterator(super.listIterator(index), set);
-+    }
-+
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        return new SetUniqueList<E>(super.subList(fromIndex, toIndex), set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inner class iterator.
-+     */
-+    static class SetListIterator <E> extends AbstractIteratorDecorator<E> {
-+
-+        protected final Set<E> set;
-+        protected E last = null;
-+
-+        protected SetListIterator(Iterator<E> it, Set<E> set) {
-+            super(it);
-+            this.set = set;
-+        }
-+
-+        public E next() {
-+            last = super.next();
-+            return last;
-+        }
-+
-+        public void remove() {
-+            super.remove();
-+            set.remove(last);
-+            last = null;
-+        }
-+    }
-+
-+    /**
-+     * Inner class iterator.
-+     */
-+    static class SetListListIterator <E> extends AbstractListIteratorDecorator<E> {
-+
-+        protected final Set<E> set;
-+        protected E last = null;
-+
-+        protected SetListListIterator(ListIterator<E> it, Set<E> set) {
-+            super(it);
-+            this.set = set;
-+        }
-+
-+        public E next() {
-+            last = super.next();
-+            return last;
-+        }
-+
-+        public E previous() {
-+            last = super.previous();
-+            return last;
-+        }
-+
-+        public void remove() {
-+            super.remove();
-+            set.remove(last);
-+            last = null;
-+        }
-+
-+        public void add(E object) {
-+            if (set.contains(object) == false) {
-+                super.add(object);
-+                set.add(object);
-+            }
-+        }
-+
-+        public void set(E object) {
-+            throw new UnsupportedOperationException("ListIterator does not support set");
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/SynchronizedList.java
-@@ -0,0 +1,165 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.collection.SynchronizedCollection;
-+
-+import java.util.Collection;
-+import java.util.List;
-+import java.util.ListIterator;
-+
-+/**
-+ * Decorates another <code>List</code> to synchronize its behaviour
-+ * for a multi-threaded environment.
-+ * <p/>
-+ * Methods are synchronized, then forwarded to the decorated list.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SynchronizedList <E> extends SynchronizedCollection<E> implements List<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -1403835447328619437L;
-+
-+    /**
-+     * Factory method to create a synchronized list.
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    public static <E> List<E> decorate(List<E> list) {
-+        return new SynchronizedList<E>(list);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    protected SynchronizedList(List<E> list) {
-+        super(list);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @param lock the lock to use, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    protected SynchronizedList(List<E> list, Object lock) {
-+        super(list, lock);
-+    }
-+
-+    /**
-+     * Gets the decorated list.
-+     *
-+     * @return the decorated list
-+     */
-+    protected List<E> getList() {
-+        return (List<E>) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void add(int index, E object) {
-+        synchronized (lock) {
-+            getList().add(index, object);
-+        }
-+    }
-+
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        synchronized (lock) {
-+            return getList().addAll(index, coll);
-+        }
-+    }
-+
-+    public E get(int index) {
-+        synchronized (lock) {
-+            return getList().get(index);
-+        }
-+    }
-+
-+    public int indexOf(Object object) {
-+        synchronized (lock) {
-+            return getList().indexOf(object);
-+        }
-+    }
-+
-+    public int lastIndexOf(Object object) {
-+        synchronized (lock) {
-+            return getList().lastIndexOf(object);
-+        }
-+    }
-+
-+    /**
-+     * Iterators must be manually synchronized.
-+     * <pre>
-+     * synchronized (coll) {
-+     *   ListIterator it = coll.listIterator();
-+     *   // do stuff with iterator
-+     * }
-+     *
-+     * @return an iterator that must be manually synchronized on the collection
-+     */
-+    public ListIterator<E> listIterator() {
-+        return getList().listIterator();
-+    }
-+
-+    /**
-+     * Iterators must be manually synchronized.
-+     * <pre>
-+     * synchronized (coll) {
-+     *   ListIterator it = coll.listIterator(3);
-+     *   // do stuff with iterator
-+     * }
-+     *
-+     * @return an iterator that must be manually synchronized on the collection
-+     */
-+    public ListIterator<E> listIterator(int index) {
-+        return getList().listIterator(index);
-+    }
-+
-+    public E remove(int index) {
-+        synchronized (lock) {
-+            return getList().remove(index);
-+        }
-+    }
-+
-+    public E set(int index, E object) {
-+        synchronized (lock) {
-+            return getList().set(index, object);
-+        }
-+    }
-+
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        synchronized (lock) {
-+            List<E> list = getList().subList(fromIndex, toIndex);
-+            // the lock is passed into the constructor here to ensure that the sublist is
-+            // synchronized on the same lock as the parent list
-+            return new SynchronizedList<E>(list, lock);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/TransformedList.java
-@@ -0,0 +1,168 @@
-+// GenericsNote: Converted, but unfortunately very little type-safety could be achieved without breaking List and ListIterator interfaces.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.Transformer;
-+import org.apache.commons.collections15.collection.TransformedCollection;
-+import org.apache.commons.collections15.iterators.AbstractListIteratorDecorator;
-+
-+import java.util.Collection;
-+import java.util.List;
-+import java.util.ListIterator;
-+
-+/**
-+ * Decorates another <code>List</code> to transform objects that are added.
-+ * <p/>
-+ * The add and set methods are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Collection contract.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedList <I,O> extends TransformedCollection<I, O> implements List {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 1077193035000013141L;
-+
-+    /**
-+     * Factory method to create a transforming list.
-+     * <p/>
-+     * If there are any elements already in the list being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param list        the list to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if list or transformer is null
-+     */
-+    public static <I,O> List<O> decorate(List<I> list, Transformer<? super I, ? extends O> transformer) {
-+        return new TransformedList<I, O>(list, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the list being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param list        the list to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if list or transformer is null
-+     */
-+    protected TransformedList(List<I> list, Transformer<? super I, ? extends O> transformer) {
-+        super(list, transformer);
-+    }
-+
-+    /**
-+     * Gets the decorated list.
-+     *
-+     * @return the decorated list
-+     */
-+    protected List<O> getList() {
-+        return (List<O>) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public O get(int index) {
-+        return getList().get(index);
-+    }
-+
-+    public int indexOf(Object object) {
-+        return getList().indexOf(object);
-+    }
-+
-+    public int lastIndexOf(Object object) {
-+        return getList().lastIndexOf(object);
-+    }
-+
-+    public Object remove(int index) {
-+        return getList().remove(index);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void add(int index, Object object) {
-+        O transformed = transform((I) object);
-+        getList().add(index, transformed);
-+    }
-+
-+    /**
-+     * Type-safe version of {@link #add(int, Object)} (but breaks List interface).
-+     */
-+    public void addTyped(int index, I object) {
-+        add(index, object);
-+    }
-+
-+    public boolean addAll(int index, Collection coll) {
-+        Collection<O> transformed = transform((Collection<? extends I>) coll);
-+        return getList().addAll(index, transformed);
-+    }
-+
-+    public ListIterator<O> listIterator() {
-+        return listIterator(0);
-+    }
-+
-+    public ListIterator<O> listIterator(int i) {
-+        return new TransformedListIterator(getList().listIterator(i));
-+    }
-+
-+    public O set(int index, Object object) {
-+        O transformed = transform((I) object);
-+        return getList().set(index, transformed);
-+    }
-+
-+    /**
-+     * Type-safe version of {@link #set(int, Object)} (but breaks List interface).
-+     */
-+    public O setTyped(int index, I object) {
-+        return set(index, object);
-+    }
-+
-+    public List<O> subList(int fromIndex, int toIndex) {
-+        List sub = getList().subList(fromIndex, toIndex);
-+        return new TransformedList<I, O>(sub, transformer);
-+    }
-+
-+    /**
-+     * Inner class Iterator for the TransformedList
-+     */
-+    protected class TransformedListIterator extends AbstractListIteratorDecorator {
-+
-+        protected TransformedListIterator(ListIterator<O> iterator) {
-+            super(iterator);
-+        }
-+
-+        public void add(Object object) {
-+            O transformed = transform((I) object);
-+            iterator.add(transformed);
-+        }
-+
-+        public void set(Object object) {
-+            O transformed = transform((I) object);
-+            iterator.set(transformed);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/TreeList.java
-@@ -0,0 +1,898 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.OrderedIterator;
-+
-+import java.util.*;
-+
-+/**
-+ * A <code>List</code> implementation that is optimised for fast insertions and
-+ * removals at any index in the list.
-+ * <p/>
-+ * This list implementation utilises a tree structure internally to ensure that
-+ * all insertions and removals are O(log n). This provides much faster performance
-+ * than both an <code>ArrayList</code> and a <code>LinkedList</code> where elements
-+ * are inserted and removed repeatedly from anywhere in the list.
-+ * <p/>
-+ * The following relative performance statistics are indicative of this class:
-+ * <pre>
-+ *              get  add  insert  iterate  remove
-+ * TreeList       3    5       1       2       1
-+ * ArrayList      1    1      40       1      40
-+ * LinkedList  5800    1     350       2     325
-+ * </pre>
-+ * <code>ArrayList</code> is a good general purpose list implementation.
-+ * It is faster than <code>TreeList</code> for most operations except inserting
-+ * and removing in the middle of the list. <code>ArrayList</code> also uses less
-+ * memory as <code>TreeList</code> uses one object per entry.
-+ * <p/>
-+ * <code>LinkedList</code> is rarely a good choice of implementation.
-+ * <code>TreeList</code> is almost always a good replacement for it, although it
-+ * does use sligtly more memory.
-+ *
-+ * @author Matt Hall, John Watkinson, Joerg Schmuecker
-+ * @author Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.1
-+ */
-+public class TreeList <E> extends AbstractList<E> {
-+    //    add; toArray; iterator; insert; get; indexOf; remove
-+    //    TreeList = 1260;7360;3080;  160;   170;3400;  170;
-+    //   ArrayList =  220;1480;1760; 6870;    50;1540; 7200;
-+    //  LinkedList =  270;7360;3350;55860;290720;2910;55200;
-+
-+    /**
-+     * The root node in the AVL tree
-+     */
-+    private AVLNode<E> root;
-+
-+    /**
-+     * The current size of the list
-+     */
-+    private int size;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new empty list.
-+     */
-+    public TreeList() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new empty list that copies the specified list.
-+     *
-+     * @param coll the collection to copy
-+     * @throws NullPointerException if the collection is null
-+     */
-+    public TreeList(Collection<? extends E> coll) {
-+        super();
-+        addAll(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the element at the specified index.
-+     *
-+     * @param index the index to retrieve
-+     * @return the element at the specified index
-+     */
-+    public E get(int index) {
-+        checkInterval(index, 0, size() - 1);
-+        return root.get(index).getValue();
-+    }
-+
-+    /**
-+     * Gets the current size of the list.
-+     *
-+     * @return the current size
-+     */
-+    public int size() {
-+        return size;
-+    }
-+
-+    /**
-+     * Gets an iterator over the list.
-+     *
-+     * @return an iterator over the list
-+     */
-+    public Iterator<E> iterator() {
-+        // override to go 75% faster
-+        return listIterator(0);
-+    }
-+
-+    /**
-+     * Gets a ListIterator over the list.
-+     *
-+     * @return the new iterator
-+     */
-+    public ListIterator<E> listIterator() {
-+        // override to go 75% faster
-+        return listIterator(0);
-+    }
-+
-+    /**
-+     * Gets a ListIterator over the list.
-+     *
-+     * @param fromIndex the index to start from
-+     * @return the new iterator
-+     */
-+    public ListIterator<E> listIterator(int fromIndex) {
-+        // override to go 75% faster
-+        // cannot use EmptyIterator as iterator.add() must work
-+        checkInterval(fromIndex, 0, size());
-+        return new TreeListIterator<E>(this, fromIndex);
-+    }
-+
-+    /**
-+     * Searches for the index of an object in the list.
-+     *
-+     * @return the index of the object, -1 if not found
-+     */
-+    public int indexOf(Object object) {
-+        // override to go 75% faster
-+        if (root == null) {
-+            return -1;
-+        }
-+        return root.indexOf((E) object, root.relativePosition);
-+    }
-+
-+    /**
-+     * Searches for the presence of an object in the list.
-+     *
-+     * @return true if the object is found
-+     */
-+    public boolean contains(Object object) {
-+        return (indexOf(object) >= 0);
-+    }
-+
-+    /**
-+     * Converts the list into an array.
-+     *
-+     * @return the list as an array
-+     */
-+    public Object[] toArray() {
-+        // override to go 20% faster
-+        Object[] array = new Object[size()];
-+        if (root != null) {
-+            root.toArray((E[]) array, root.relativePosition);
-+        }
-+        return array;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Adds a new element to the list.
-+     *
-+     * @param index the index to add before
-+     * @param obj   the element to add
-+     */
-+    public void add(int index, E obj) {
-+        modCount++;
-+        checkInterval(index, 0, size());
-+        if (root == null) {
-+            root = new AVLNode<E>(index, obj, null, null);
-+        } else {
-+            root = root.insert(index, obj);
-+        }
-+        size++;
-+    }
-+
-+    /**
-+     * Sets the element at the specified index.
-+     *
-+     * @param index the index to set
-+     * @param obj   the object to store at the specified index
-+     * @return the previous object at that index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public E set(int index, E obj) {
-+        checkInterval(index, 0, size() - 1);
-+        AVLNode<E> node = root.get(index);
-+        E result = node.value;
-+        node.setValue(obj);
-+        return result;
-+    }
-+
-+    /**
-+     * Removes the element at the specified index.
-+     *
-+     * @param index the index to remove
-+     * @return the previous object at that index
-+     */
-+    public E remove(int index) {
-+        modCount++;
-+        checkInterval(index, 0, size() - 1);
-+        E result = get(index);
-+        root = root.remove(index);
-+        size--;
-+        return result;
-+    }
-+
-+    /**
-+     * Clears the list, removing all entries.
-+     */
-+    public void clear() {
-+        modCount++;
-+        root = null;
-+        size = 0;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks whether the index is valid.
-+     *
-+     * @param index      the index to check
-+     * @param startIndex the first allowed index
-+     * @param endIndex   the last allowed index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    private void checkInterval(int index, int startIndex, int endIndex) {
-+        if (index < startIndex || index > endIndex) {
-+            throw new IndexOutOfBoundsException("Invalid index:" + index + ", size=" + size());
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implements an AVLNode which keeps the offset updated.
-+     * <p/>
-+     * This node contains the real work.
-+     * TreeList is just there to implement {@link java.util.List}.
-+     * The nodes don't know the index of the object they are holding.  They
-+     * do know however their position relative to their parent node.
-+     * This allows to calculate the index of a node while traversing the tree.
-+     * <p/>
-+     * The Faedelung calculation stores a flag for both the left and right child
-+     * to indicate if they are a child (false) or a link as in linked list (true).
-+     */
-+    static class AVLNode <T> {
-+        /**
-+         * The left child node or the predecessor if {@link #leftIsPrevious}.
-+         */
-+        private AVLNode<T> left;
-+        /**
-+         * Flag indicating that left reference is not a subtree but the predecessor.
-+         */
-+        private boolean leftIsPrevious;
-+        /**
-+         * The right child node or the successor if {@link #rightIsNext}.
-+         */
-+        private AVLNode<T> right;
-+        /**
-+         * Flag indicating that right reference is not a subtree but the successor.
-+         */
-+        private boolean rightIsNext;
-+        /**
-+         * How many levels of left/right are below this one.
-+         */
-+        private int height;
-+        /**
-+         * The relative position, root holds absolute position.
-+         */
-+        private int relativePosition;
-+        /**
-+         * The stored element.
-+         */
-+        private T value;
-+
-+        /**
-+         * Constructs a new node with a relative position.
-+         *
-+         * @param relativePosition the relative position of the node
-+         * @param obj              the value for the ndoe
-+         * @param rightFollower    the node with the value following this one
-+         * @param leftFollower     the node with the value leading this one
-+         */
-+        private AVLNode(int relativePosition, T obj, AVLNode<T> rightFollower, AVLNode<T> leftFollower) {
-+            this.relativePosition = relativePosition;
-+            value = obj;
-+            rightIsNext = true;
-+            leftIsPrevious = true;
-+            right = rightFollower;
-+            left = leftFollower;
-+        }
-+
-+        /**
-+         * Gets the value.
-+         *
-+         * @return the value of this node
-+         */
-+        T getValue() {
-+            return value;
-+        }
-+
-+        /**
-+         * Sets the value.
-+         *
-+         * @param obj the value to store
-+         */
-+        void setValue(T obj) {
-+            this.value = obj;
-+        }
-+
-+        /**
-+         * Locate the element with the given index relative to the
-+         * offset of the parent of this node.
-+         */
-+        AVLNode<T> get(int index) {
-+            int indexRelativeToMe = index - relativePosition;
-+
-+            if (indexRelativeToMe == 0) {
-+                return this;
-+            }
-+
-+            AVLNode<T> nextNode = ((indexRelativeToMe < 0) ? getLeftSubTree() : getRightSubTree());
-+            if (nextNode == null) {
-+                return null;
-+            }
-+            return nextNode.get(indexRelativeToMe);
-+        }
-+
-+        /**
-+         * Locate the index that contains the specified object.
-+         */
-+        int indexOf(T object, int index) {
-+            if (getLeftSubTree() != null) {
-+                int result = left.indexOf(object, index + left.relativePosition);
-+                if (result != -1) {
-+                    return result;
-+                }
-+            }
-+            if (value == null ? value == object : value.equals(object)) {
-+                return index;
-+            }
-+            if (getRightSubTree() != null) {
-+                return right.indexOf(object, index + right.relativePosition);
-+            }
-+            return -1;
-+        }
-+
-+        /**
-+         * Stores the node and its children into the array specified.
-+         *
-+         * @param array the array to be filled
-+         * @param index the index of this node
-+         */
-+        void toArray(T[] array, int index) {
-+            array[index] = value;
-+            if (getLeftSubTree() != null) {
-+                left.toArray(array, index + left.relativePosition);
-+            }
-+            if (getRightSubTree() != null) {
-+                right.toArray(array, index + right.relativePosition);
-+            }
-+        }
-+
-+        /**
-+         * Gets the next node in the list after this one.
-+         *
-+         * @return the next node
-+         */
-+        AVLNode<T> next() {
-+            if (rightIsNext || right == null) {
-+                return right;
-+            }
-+            return right.min();
-+        }
-+
-+        /**
-+         * Gets the node in the list before this one.
-+         *
-+         * @return the previous node
-+         */
-+        AVLNode<T> previous() {
-+            if (leftIsPrevious || left == null) {
-+                return left;
-+            }
-+            return left.max();
-+        }
-+
-+        /**
-+         * Inserts a node at the position index.
-+         *
-+         * @param index is the index of the position relative to the position of
-+         *              the parent node.
-+         * @param obj   is the object to be stored in the position.
-+         */
-+        AVLNode<T> insert(int index, T obj) {
-+            int indexRelativeToMe = index - relativePosition;
-+
-+            if (indexRelativeToMe <= 0) {
-+                return insertOnLeft(indexRelativeToMe, obj);
-+            } else {
-+                return insertOnRight(indexRelativeToMe, obj);
-+            }
-+        }
-+
-+        private AVLNode<T> insertOnLeft(int indexRelativeToMe, T obj) {
-+            AVLNode<T> ret = this;
-+
-+            if (getLeftSubTree() == null) {
-+                setLeft(new AVLNode<T>(-1, obj, this, left), null);
-+            } else {
-+                setLeft(left.insert(indexRelativeToMe, obj), null);
-+            }
-+
-+            if (relativePosition >= 0) {
-+                relativePosition++;
-+            }
-+            ret = balance();
-+            recalcHeight();
-+            return ret;
-+        }
-+
-+        private AVLNode<T> insertOnRight(int indexRelativeToMe, T obj) {
-+            AVLNode<T> ret = this;
-+
-+            if (getRightSubTree() == null) {
-+                setRight(new AVLNode<T>(+1, obj, right, this), null);
-+            } else {
-+                setRight(right.insert(indexRelativeToMe, obj), null);
-+            }
-+            if (relativePosition < 0) {
-+                relativePosition--;
-+            }
-+            ret = balance();
-+            recalcHeight();
-+            return ret;
-+        }
-+
-+        //-----------------------------------------------------------------------
-+        /**
-+         * Gets the left node, returning null if its a faedelung.
-+         */
-+        private AVLNode<T> getLeftSubTree() {
-+            return (leftIsPrevious ? null : left);
-+        }
-+
-+        /**
-+         * Gets the right node, returning null if its a faedelung.
-+         */
-+        private AVLNode<T> getRightSubTree() {
-+            return (rightIsNext ? null : right);
-+        }
-+
-+        /**
-+         * Gets the rightmost child of this node.
-+         *
-+         * @return the rightmost child (greatest index)
-+         */
-+        private AVLNode<T> max() {
-+            return (getRightSubTree() == null) ? this : right.max();
-+        }
-+
-+        /**
-+         * Gets the leftmost child of this node.
-+         *
-+         * @return the leftmost child (smallest index)
-+         */
-+        private AVLNode<T> min() {
-+            return (getLeftSubTree() == null) ? this : left.min();
-+        }
-+
-+        /**
-+         * Removes the node at a given position.
-+         *
-+         * @param index is the index of the element to be removed relative to the position of
-+         *              the parent node of the current node.
-+         */
-+        AVLNode<T> remove(int index) {
-+            int indexRelativeToMe = index - relativePosition;
-+
-+            if (indexRelativeToMe == 0) {
-+                return removeSelf();
-+            }
-+            if (indexRelativeToMe > 0) {
-+                setRight(right.remove(indexRelativeToMe), right.right);
-+                if (relativePosition < 0) {
-+                    relativePosition++;
-+                }
-+            } else {
-+                setLeft(left.remove(indexRelativeToMe), left.left);
-+                if (relativePosition > 0) {
-+                    relativePosition--;
-+                }
-+            }
-+            recalcHeight();
-+            return balance();
-+        }
-+
-+        private AVLNode<T> removeMax() {
-+            if (getRightSubTree() == null) {
-+                return removeSelf();
-+            }
-+            setRight(right.removeMax(), right.right);
-+            if (relativePosition < 0) {
-+                relativePosition++;
-+            }
-+            recalcHeight();
-+            return balance();
-+        }
-+
-+        private AVLNode<T> removeMin() {
-+            if (getLeftSubTree() == null) {
-+                return removeSelf();
-+            }
-+            setLeft(left.removeMin(), left.left);
-+            if (relativePosition > 0) {
-+                relativePosition--;
-+            }
-+            recalcHeight();
-+            return balance();
-+        }
-+
-+        private AVLNode<T> removeSelf() {
-+            if (getRightSubTree() == null && getLeftSubTree() == null)
-+                return null;
-+            if (getRightSubTree() == null) {
-+                if (relativePosition > 0) {
-+                    left.relativePosition += relativePosition + (relativePosition > 0 ? 0 : 1);
-+                }
-+                left.max().setRight(null, right);
-+                return left;
-+            }
-+            if (getLeftSubTree() == null) {
-+                right.relativePosition += relativePosition - (relativePosition < 0 ? 0 : 1);
-+                right.min().setLeft(null, left);
-+                return right;
-+            }
-+
-+            if (heightRightMinusLeft() > 0) {
-+                AVLNode<T> rightMin = right.min();
-+                value = rightMin.value;
-+                if (leftIsPrevious) {
-+                    left = rightMin.left;
-+                }
-+                right = right.removeMin();
-+                if (relativePosition < 0) {
-+                    relativePosition++;
-+                }
-+            } else {
-+                AVLNode<T> leftMax = left.max();
-+                value = leftMax.value;
-+                if (rightIsNext) {
-+                    right = leftMax.right;
-+                }
-+                left = left.removeMax();
-+                if (relativePosition > 0) {
-+                    relativePosition--;
-+                }
-+            }
-+            recalcHeight();
-+            return this;
-+        }
-+
-+        //-----------------------------------------------------------------------
-+        /**
-+         * Balances according to the AVL algorithm.
-+         */
-+        private AVLNode<T> balance() {
-+            switch (heightRightMinusLeft()) {
-+                case 1:
-+                case 0:
-+                case -1:
-+                    return this;
-+                case -2:
-+                    if (left.heightRightMinusLeft() > 0) {
-+                        setLeft(left.rotateLeft(), null);
-+                    }
-+                    return rotateRight();
-+                case 2:
-+                    if (right.heightRightMinusLeft() < 0) {
-+                        setRight(right.rotateRight(), null);
-+                    }
-+                    return rotateLeft();
-+                default :
-+                    throw new RuntimeException("tree inconsistent!");
-+            }
-+        }
-+
-+        /**
-+         * Gets the relative position.
-+         */
-+        private int getOffset(AVLNode<T> node) {
-+            if (node == null) {
-+                return 0;
-+            }
-+            return node.relativePosition;
-+        }
-+
-+        /**
-+         * Sets the relative position.
-+         */
-+        private int setOffset(AVLNode<T> node, int newOffest) {
-+            if (node == null) {
-+                return 0;
-+            }
-+            int oldOffset = getOffset(node);
-+            node.relativePosition = newOffest;
-+            return oldOffset;
-+        }
-+
-+        /**
-+         * Sets the height by calculation.
-+         */
-+        private void recalcHeight() {
-+            height = Math.max(getLeftSubTree() == null ? -1 : getLeftSubTree().height, getRightSubTree() == null ? -1 : getRightSubTree().height) + 1;
-+        }
-+
-+        /**
-+         * Returns the height of the node or -1 if the node is null.
-+         */
-+        private int getHeight(AVLNode<T> node) {
-+            return (node == null ? -1 : node.height);
-+        }
-+
-+        /**
-+         * Returns the height difference right - left
-+         */
-+        private int heightRightMinusLeft() {
-+            return getHeight(getRightSubTree()) - getHeight(getLeftSubTree());
-+        }
-+
-+        private AVLNode<T> rotateLeft() {
-+            AVLNode<T> newTop = right; // can't be faedelung!
-+            AVLNode<T> movedNode = getRightSubTree().getLeftSubTree();
-+
-+            int newTopPosition = relativePosition + getOffset(newTop);
-+            int myNewPosition = -newTop.relativePosition;
-+            int movedPosition = getOffset(newTop) + getOffset(movedNode);
-+
-+            setRight(movedNode, newTop);
-+            newTop.setLeft(this, null);
-+
-+            setOffset(newTop, newTopPosition);
-+            setOffset(this, myNewPosition);
-+            setOffset(movedNode, movedPosition);
-+            return newTop;
-+        }
-+
-+        private AVLNode<T> rotateRight() {
-+            AVLNode<T> newTop = left; // can't be faedelung
-+            AVLNode<T> movedNode = getLeftSubTree().getRightSubTree();
-+
-+            int newTopPosition = relativePosition + getOffset(newTop);
-+            int myNewPosition = -newTop.relativePosition;
-+            int movedPosition = getOffset(newTop) + getOffset(movedNode);
-+
-+            setLeft(movedNode, newTop);
-+            newTop.setRight(this, null);
-+
-+            setOffset(newTop, newTopPosition);
-+            setOffset(this, myNewPosition);
-+            setOffset(movedNode, movedPosition);
-+            return newTop;
-+        }
-+
-+        private void setLeft(AVLNode<T> node, AVLNode<T> previous) {
-+            leftIsPrevious = (node == null);
-+            left = (leftIsPrevious ? previous : node);
-+            recalcHeight();
-+        }
-+
-+        private void setRight(AVLNode<T> node, AVLNode<T> next) {
-+            rightIsNext = (node == null);
-+            right = (rightIsNext ? next : node);
-+            recalcHeight();
-+        }
-+
-+        //      private void checkFaedelung() {
-+        //          AVLNode maxNode = left.max();
-+        //          if (!maxNode.rightIsFaedelung || maxNode.right != this) {
-+        //              throw new RuntimeException(maxNode + " should right-faedel to " + this);
-+        //          }
-+        //          AVLNode minNode = right.min();
-+        //          if (!minNode.leftIsFaedelung || minNode.left != this) {
-+        //              throw new RuntimeException(maxNode + " should left-faedel to " + this);
-+        //          }
-+        //      }
-+        //
-+        //        private int checkTreeDepth() {
-+        //            int hright = (getRightSubTree() == null ? -1 : getRightSubTree().checkTreeDepth());
-+        //            //          System.out.print("checkTreeDepth");
-+        //            //          System.out.print(this);
-+        //            //          System.out.print(" left: ");
-+        //            //          System.out.print(_left);
-+        //            //          System.out.print(" right: ");
-+        //            //          System.out.println(_right);
-+        //
-+        //            int hleft = (left == null ? -1 : left.checkTreeDepth());
-+        //            if (height != Math.max(hright, hleft) + 1) {
-+        //                throw new RuntimeException(
-+        //                    "height should be max" + hleft + "," + hright + " but is " + height);
-+        //            }
-+        //            return height;
-+        //        }
-+        //
-+        //        private int checkLeftSubNode() {
-+        //            if (getLeftSubTree() == null) {
-+        //                return 0;
-+        //            }
-+        //            int count = 1 + left.checkRightSubNode();
-+        //            if (left.relativePosition != -count) {
-+        //                throw new RuntimeException();
-+        //            }
-+        //            return count + left.checkLeftSubNode();
-+        //        }
-+        //
-+        //        private int checkRightSubNode() {
-+        //            AVLNode right = getRightSubTree();
-+        //            if (right == null) {
-+        //                return 0;
-+        //            }
-+        //            int count = 1;
-+        //            count += right.checkLeftSubNode();
-+        //            if (right.relativePosition != count) {
-+        //                throw new RuntimeException();
-+        //            }
-+        //            return count + right.checkRightSubNode();
-+        //        }
-+
-+        /**
-+         * Used for debugging.
-+         */
-+        public String toString() {
-+            return "AVLNode(" + relativePosition + "," + (left != null) + "," + value + "," + (getRightSubTree() != null) + ", faedelung " + rightIsNext + " )";
-+        }
-+    }
-+
-+    /**
-+     * A list iterator over the linked list.
-+     */
-+    static class TreeListIterator <E> implements ListIterator<E>, OrderedIterator<E> {
-+        /**
-+         * The parent list
-+         */
-+        protected final TreeList<E> parent;
-+        /**
-+         * The node that will be returned by {@link #next()}. If this is equal
-+         * to {@link AbstractLinkedList#header} then there are no more values to return.
-+         */
-+        protected AVLNode<E> next;
-+        /**
-+         * The index of {@link #next}.
-+         */
-+        protected int nextIndex;
-+        /**
-+         * The last node that was returned by {@link #next()} or {@link
-+         * #previous()}. Set to <code>null</code> if {@link #next()} or {@link
-+         * #previous()} haven't been called, or if the node has been removed
-+         * with {@link #remove()} or a new node added with {@link #add(Object)}.
-+         * Should be accessed through {@link #getLastNodeReturned()} to enforce
-+         * this behaviour.
-+         */
-+        protected AVLNode<E> current;
-+        /**
-+         * The index of {@link #current}.
-+         */
-+        protected int currentIndex;
-+        /**
-+         * The modification count that the list is expected to have. If the list
-+         * doesn't have this count, then a
-+         * {@link java.util.ConcurrentModificationException} may be thrown by
-+         * the operations.
-+         */
-+        protected int expectedModCount;
-+
-+        /**
-+         * Create a ListIterator for a list.
-+         *
-+         * @param parent    the parent list
-+         * @param fromIndex the index to start at
-+         */
-+        protected TreeListIterator(TreeList<E> parent, int fromIndex) throws IndexOutOfBoundsException {
-+            super();
-+            this.parent = parent;
-+            this.expectedModCount = parent.modCount;
-+            this.next = (parent.root == null ? null : parent.root.get(fromIndex));
-+            this.nextIndex = fromIndex;
-+        }
-+
-+        /**
-+         * Checks the modification count of the list is the value that this
-+         * object expects.
-+         *
-+         * @throws ConcurrentModificationException
-+         *          If the list's modification
-+         *          count isn't the value that was expected.
-+         */
-+        protected void checkModCount() {
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+        }
-+
-+        public boolean hasNext() {
-+            return (nextIndex < parent.size());
-+        }
-+
-+        public E next() {
-+            checkModCount();
-+            if (!hasNext()) {
-+                throw new NoSuchElementException("No element at index " + nextIndex + ".");
-+            }
-+            if (next == null) {
-+                next = parent.root.get(nextIndex);
-+            }
-+            E value = next.getValue();
-+            current = next;
-+            currentIndex = nextIndex++;
-+            next = next.next();
-+            return value;
-+        }
-+
-+        public boolean hasPrevious() {
-+            return (nextIndex > 0);
-+        }
-+
-+        public E previous() {
-+            checkModCount();
-+            if (!hasPrevious()) {
-+                throw new NoSuchElementException("Already at start of list.");
-+            }
-+            if (next == null) {
-+                next = parent.root.get(nextIndex - 1);
-+            } else {
-+                next = next.previous();
-+            }
-+            E value = next.getValue();
-+            current = next;
-+            currentIndex = --nextIndex;
-+            return value;
-+        }
-+
-+        public int nextIndex() {
-+            return nextIndex;
-+        }
-+
-+        public int previousIndex() {
-+            return nextIndex() - 1;
-+        }
-+
-+        public void remove() {
-+            checkModCount();
-+            if (current == null) {
-+                throw new IllegalStateException();
-+            }
-+            parent.remove(currentIndex);
-+            current = null;
-+            currentIndex = -1;
-+            nextIndex--;
-+            expectedModCount++;
-+        }
-+
-+        public void set(E obj) {
-+            checkModCount();
-+            if (current == null) {
-+                throw new IllegalStateException();
-+            }
-+            current.setValue(obj);
-+        }
-+
-+        public void add(E obj) {
-+            checkModCount();
-+            parent.add(nextIndex, obj);
-+            current = null;
-+            currentIndex = -1;
-+            nextIndex++;
-+            expectedModCount++;
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/TypedList.java
-@@ -0,0 +1,60 @@
-+// GenericsNote: deprecated and useless
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+import java.util.List;
-+
-+/**
-+ * Decorates another <code>List</code> to validate that elements
-+ * added are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ * @deprecated Java Generics makes this class obsolete.
-+ */
-+public class TypedList {
-+
-+    /**
-+     * Factory method to create a typed list.
-+     * <p/>
-+     * If there are any elements already in the list being decorated, they
-+     * are validated.
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @param type the type to allow into the collection, must not be null
-+     * @throws IllegalArgumentException if list or type is null
-+     * @throws IllegalArgumentException if the list contains invalid elements
-+     */
-+    public static List decorate(List list, Class type) {
-+        return new PredicatedList(list, InstanceofPredicate.getInstance(type));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedList() {
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/UnmodifiableList.java
-@@ -0,0 +1,127 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.list;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+import org.apache.commons.collections15.iterators.UnmodifiableListIterator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.List;
-+import java.util.ListIterator;
-+
-+/**
-+ * Decorates another <code>List</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableList <E> extends AbstractSerializableListDecorator<E> implements Unmodifiable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 6595182819922443652L;
-+
-+    /**
-+     * Factory method to create an unmodifiable list.
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    public static <E> List<E> decorate(List<E> list) {
-+        if (list instanceof Unmodifiable) {
-+            return list;
-+        }
-+        return new UnmodifiableList<E>(list);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    private UnmodifiableList(List<E> list) {
-+        super(list);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public ListIterator<E> listIterator() {
-+        return UnmodifiableListIterator.decorate(getList().listIterator());
-+    }
-+
-+    public ListIterator<E> listIterator(int index) {
-+        return UnmodifiableListIterator.decorate(getList().listIterator(index));
-+    }
-+
-+    public void add(int index, E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public E remove(int index) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public E set(int index, E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public List<E> subList(int fromIndex, int toIndex) {
-+        List<E> sub = getList().subList(fromIndex, toIndex);
-+        return new UnmodifiableList<E>(sub);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/list/package.html
-@@ -0,0 +1,41 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:32 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link java.util.List List} interface.
-+<p>
-+The following implementations are provided in the package:
-+<ul>
-+<li>TreeList - a list that is optimised for insertions and removals at any index in the list
-+<li>CursorableLinkedList - a list that can be modified while it's listIterator (cursor) is being used
-+<li>NodeCachingLinkedList - a linked list that caches the storage nodes for a performance gain
-+</ul>
-+<p>
-+The following decorators are provided in the package:
-+<ul>
-+<li>Synchronized - synchronizes method access for multi-threaded environments
-+<li>Unmodifiable - ensures the collection cannot be altered
-+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
-+<li>Typed - ensures that only elements that are of a specific type can be added
-+<li>Transformed - transforms each element added
-+<li>FixedSize - ensures that the size of the list cannot change
-+<li>Lazy - creates objects in the list on demand
-+<li>SetUnique - a list that avoids duplicate entries like a Set
-+</ul>
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/AbstractHashedMap.java
-@@ -0,0 +1,1344 @@
-+// GenericsNote: Converted -- However, null keys will now be represented in the internal structures, a big change.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.IterableMap;
-+import org.apache.commons.collections15.KeyValue;
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.iterators.EmptyIterator;
-+import org.apache.commons.collections15.iterators.EmptyMapIterator;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.util.*;
-+
-+/**
-+ * An abstract implementation of a hash-based map which provides numerous points for
-+ * subclasses to override.
-+ * <p/>
-+ * This class implements all the features necessary for a subclass hash-based map.
-+ * Key-value entries are stored in instances of the <code>HashEntry</code> class,
-+ * which can be overridden and replaced. The iterators can similarly be replaced,
-+ * without the need to replace the KeySet, EntrySet and Values view classes.
-+ * <p/>
-+ * Overridable methods are provided to change the default hashing behaviour, and
-+ * to change how entries are added to and removed from the map. Hopefully, all you
-+ * need for unusual subclasses is here.
-+ * <p/>
-+ * NOTE: From Commons Collections 3.1 this class extends AbstractMap.
-+ * This is to provide backwards compatibility for ReferenceMap between v3.0 and v3.1.
-+ * This extends clause will be removed in v4.0.
-+ *
-+ * @author java util HashMap
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class AbstractHashedMap <K,V> extends AbstractMap<K, V> implements IterableMap<K, V> {
-+
-+    protected static final String NO_NEXT_ENTRY = "No next() entry in the iteration";
-+    protected static final String NO_PREVIOUS_ENTRY = "No previous() entry in the iteration";
-+    protected static final String REMOVE_INVALID = "remove() can only be called once after next()";
-+    protected static final String GETKEY_INVALID = "getKey() can only be called after next() and before remove()";
-+    protected static final String GETVALUE_INVALID = "getValue() can only be called after next() and before remove()";
-+    protected static final String SETVALUE_INVALID = "setValue() can only be called after next() and before remove()";
-+
-+    /**
-+     * The default capacity to use
-+     */
-+    protected static final int DEFAULT_CAPACITY = 16;
-+    /**
-+     * The default threshold to use
-+     */
-+    protected static final int DEFAULT_THRESHOLD = 12;
-+    /**
-+     * The default load factor to use
-+     */
-+    protected static final float DEFAULT_LOAD_FACTOR = 0.75f;
-+    /**
-+     * The maximum capacity allowed
-+     */
-+    protected static final int MAXIMUM_CAPACITY = 1 << 30;
-+    /**
-+     * An object for masking null
-+     */
-+    protected static final Object NULL = new Object();
-+
-+    /**
-+     * Load factor, normally 0.75
-+     */
-+    protected transient float loadFactor;
-+    /**
-+     * The size of the map
-+     */
-+    protected transient int size;
-+    /**
-+     * Map entries
-+     */
-+    protected transient HashEntry<K, V>[] data;
-+    /**
-+     * Size at which to rehash
-+     */
-+    protected transient int threshold;
-+    /**
-+     * Modification count for iterators
-+     */
-+    protected transient int modCount;
-+    /**
-+     * Entry set
-+     */
-+    protected transient EntrySet<K, V> entrySet;
-+    /**
-+     * Key set
-+     */
-+    protected transient KeySet<K, V> keySet;
-+    /**
-+     * Values
-+     */
-+    protected transient Values<K, V> values;
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     */
-+    protected AbstractHashedMap() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor which performs no validation on the passed in parameters.
-+     *
-+     * @param initialCapacity the initial capacity, must be a power of two
-+     * @param loadFactor      the load factor, must be > 0.0f and generally < 1.0f
-+     * @param threshold       the threshold, must be sensible
-+     */
-+    protected AbstractHashedMap(int initialCapacity, float loadFactor, int threshold) {
-+        super();
-+        this.loadFactor = loadFactor;
-+        this.data = new HashEntry[initialCapacity];
-+        this.threshold = threshold;
-+        init();
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * default load factor.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     */
-+    protected AbstractHashedMap(int initialCapacity) {
-+        this(initialCapacity, DEFAULT_LOAD_FACTOR);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @param loadFactor      the load factor
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     * @throws IllegalArgumentException if the load factor is less than or equal to zero
-+     */
-+    protected AbstractHashedMap(int initialCapacity, float loadFactor) {
-+        super();
-+        if (initialCapacity < 1) {
-+            throw new IllegalArgumentException("Initial capacity must be greater than 0");
-+        }
-+        if (loadFactor <= 0.0f || Float.isNaN(loadFactor)) {
-+            throw new IllegalArgumentException("Load factor must be greater than 0");
-+        }
-+        this.loadFactor = loadFactor;
-+        this.threshold = calculateThreshold(initialCapacity, loadFactor);
-+        initialCapacity = calculateNewCapacity(initialCapacity);
-+        this.data = new HashEntry[initialCapacity];
-+        init();
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException if the map is null
-+     */
-+    protected AbstractHashedMap(Map<? extends K, ? extends V> map) {
-+        this(Math.max(2 * map.size(), DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
-+        putAll(map);
-+    }
-+
-+    /**
-+     * Initialise subclasses during construction, cloning or deserialization.
-+     */
-+    protected void init() {
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the value mapped to the key specified.
-+     *
-+     * @param key the key
-+     * @return the mapped value, null if no match
-+     */
-+    public V get(Object key) {
-+        int hashCode = hash((key == null) ? NULL : key);
-+        HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
-+                return entry.getValue();
-+            }
-+            entry = entry.next;
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets the size of the map.
-+     *
-+     * @return the size
-+     */
-+    public int size() {
-+        return size;
-+    }
-+
-+    /**
-+     * Checks whether the map is currently empty.
-+     *
-+     * @return true if the map is currently size zero
-+     */
-+    public boolean isEmpty() {
-+        return (size == 0);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks whether the map contains the specified key.
-+     *
-+     * @param key the key to search for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsKey(Object key) {
-+        int hashCode = hash((key == null) ? NULL : key);
-+        HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(key, entry.getKey())) {
-+                return true;
-+            }
-+            entry = entry.next;
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Checks whether the map contains the specified value.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the value
-+     */
-+    public boolean containsValue(Object value) {
-+        if (value == null) {
-+            for (int i = 0, isize = data.length; i < isize; i++) {
-+                HashEntry entry = data[i];
-+                while (entry != null) {
-+                    if (entry.getValue() == null) {
-+                        return true;
-+                    }
-+                    entry = entry.next;
-+                }
-+            }
-+        } else {
-+            for (int i = 0, isize = data.length; i < isize; i++) {
-+                HashEntry entry = data[i];
-+                while (entry != null) {
-+                    if (isEqualValue(value, entry.getValue())) {
-+                        return true;
-+                    }
-+                    entry = entry.next;
-+                }
-+            }
-+        }
-+        return false;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Puts a key-value mapping into this map.
-+     *
-+     * @param key   the key to add
-+     * @param value the value to add
-+     * @return the value previously mapped to this key, null if none
-+     */
-+    public V put(K key, V value) {
-+        int hashCode = hash((key == null) ? NULL : key);
-+        int index = hashIndex(hashCode, data.length);
-+        HashEntry<K, V> entry = data[index];
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(key, entry.getKey())) {
-+                V oldValue = entry.getValue();
-+                updateEntry(entry, value);
-+                return oldValue;
-+            }
-+            entry = entry.next;
-+        }
-+        addMapping(index, hashCode, key, value);
-+        return null;
-+    }
-+
-+    /**
-+     * Puts all the values from the specified map into this map.
-+     * <p/>
-+     * This implementation iterates around the specified map and
-+     * uses {@link #put(Object, Object)}.
-+     *
-+     * @param map the map to add
-+     * @throws NullPointerException if the map is null
-+     */
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        int mapSize = map.size();
-+        if (mapSize == 0) {
-+            return;
-+        }
-+        int newSize = (int) ((size + mapSize) / loadFactor + 1);
-+        ensureCapacity(calculateNewCapacity(newSize));
-+        // Have to cast here because of compiler inference problems.
-+        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<? extends K, ? extends V> entry = (Map.Entry<? extends K, ? extends V>) it.next();
-+            put(entry.getKey(), entry.getValue());
-+        }
-+    }
-+
-+    /**
-+     * Removes the specified mapping from this map.
-+     *
-+     * @param key the mapping to remove
-+     * @return the value mapped to the removed key, null if key not in map
-+     */
-+    public V remove(Object key) {
-+        int hashCode = hash((key == null) ? NULL : key);
-+        int index = hashIndex(hashCode, data.length);
-+        HashEntry<K, V> entry = data[index];
-+        HashEntry<K, V> previous = null;
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(key, entry.getKey())) {
-+                V oldValue = entry.getValue();
-+                removeMapping(entry, index, previous);
-+                return oldValue;
-+            }
-+            previous = entry;
-+            entry = entry.next;
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Clears the map, resetting the size to zero and nullifying references
-+     * to avoid garbage collection issues.
-+     */
-+    public void clear() {
-+        modCount++;
-+        HashEntry[] data = this.data;
-+        for (int i = data.length - 1; i >= 0; i--) {
-+            data[i] = null;
-+        }
-+        size = 0;
-+    }
-+
-+    /**
-+     * Gets the hash code for the key specified.
-+     * This implementation uses the additional hashing routine from JDK1.4.
-+     * Subclasses can override this to return alternate hash codes.
-+     *
-+     * @param key the key to get a hash code for
-+     * @return the hash code
-+     */
-+    protected int hash(Object key) {
-+        // same as JDK 1.4
-+        int h = key.hashCode();
-+        h += ~(h << 9);
-+        h ^= (h >>> 14);
-+        h += (h << 4);
-+        h ^= (h >>> 10);
-+        return h;
-+    }
-+
-+    /**
-+     * Compares two keys, in internal converted form, to see if they are equal.
-+     * This implementation uses the equals method.
-+     * Subclasses can override this to match differently.
-+     *
-+     * @param key1 the first key to compare passed in from outside
-+     * @param key2 the second key extracted from the entry via <code>entry.key</code>
-+     * @return true if equal
-+     */
-+    protected boolean isEqualKey(Object key1, Object key2) {
-+        return (key1 == key2 || ((key1 != null) && key1.equals(key2)));
-+    }
-+
-+    /**
-+     * Compares two values, in external form, to see if they are equal.
-+     * This implementation uses the equals method and assumes neither value is null.
-+     * Subclasses can override this to match differently.
-+     *
-+     * @param value1 the first value to compare passed in from outside
-+     * @param value2 the second value extracted from the entry via <code>getValue()</code>
-+     * @return true if equal
-+     */
-+    protected boolean isEqualValue(Object value1, Object value2) {
-+        return (value1 == value2 || value1.equals(value2));
-+    }
-+
-+    /**
-+     * Gets the index into the data storage for the hashCode specified.
-+     * This implementation uses the least significant bits of the hashCode.
-+     * Subclasses can override this to return alternate bucketing.
-+     *
-+     * @param hashCode the hash code to use
-+     * @param dataSize the size of the data to pick a bucket from
-+     * @return the bucket index
-+     */
-+    protected int hashIndex(int hashCode, int dataSize) {
-+        return hashCode & (dataSize - 1);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the entry mapped to the key specified.
-+     * <p/>
-+     * This method exists for subclasses that may need to perform a multi-step
-+     * process accessing the entry. The public methods in this class don't use this
-+     * method to gain a small performance boost.
-+     *
-+     * @param key the key
-+     * @return the entry, null if no match
-+     */
-+    protected HashEntry<K, V> getEntry(Object key) {
-+        int hashCode = hash((key == null) ? NULL : key);
-+        HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(key, entry.getKey())) {
-+                return entry;
-+            }
-+            entry = entry.next;
-+        }
-+        return null;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Updates an existing key-value mapping to change the value.
-+     * <p/>
-+     * This implementation calls <code>setValue()</code> on the entry.
-+     * Subclasses could override to handle changes to the map.
-+     *
-+     * @param entry    the entry to update
-+     * @param newValue the new value to store
-+     */
-+    protected void updateEntry(HashEntry<K, V> entry, V newValue) {
-+        entry.setValue(newValue);
-+    }
-+
-+    /**
-+     * Reuses an existing key-value mapping, storing completely new data.
-+     * <p/>
-+     * This implementation sets all the data fields on the entry.
-+     * Subclasses could populate additional entry fields.
-+     *
-+     * @param entry     the entry to update, not null
-+     * @param hashIndex the index in the data array
-+     * @param hashCode  the hash code of the key to add
-+     * @param key       the key to add
-+     * @param value     the value to add
-+     */
-+    protected void reuseEntry(HashEntry<K, V> entry, int hashIndex, int hashCode, K key, V value) {
-+        entry.next = data[hashIndex];
-+        entry.hashCode = hashCode;
-+        entry.key = key;
-+        entry.value = value;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Adds a new key-value mapping into this map.
-+     * <p/>
-+     * This implementation calls <code>createEntry()</code>, <code>addEntry()</code>
-+     * and <code>checkCapacity()</code>.
-+     * It also handles changes to <code>modCount</code> and <code>size</code>.
-+     * Subclasses could override to fully control adds to the map.
-+     *
-+     * @param hashIndex the index into the data array to store at
-+     * @param hashCode  the hash code of the key to add
-+     * @param key       the key to add
-+     * @param value     the value to add
-+     */
-+    protected void addMapping(int hashIndex, int hashCode, K key, V value) {
-+        modCount++;
-+        HashEntry<K, V> entry = createEntry(data[hashIndex], hashCode, key, value);
-+        addEntry(entry, hashIndex);
-+        size++;
-+        checkCapacity();
-+    }
-+
-+    /**
-+     * Creates an entry to store the key-value data.
-+     * <p/>
-+     * This implementation creates a new HashEntry instance.
-+     * Subclasses can override this to return a different storage class,
-+     * or implement caching.
-+     *
-+     * @param next     the next entry in sequence
-+     * @param hashCode the hash code to use
-+     * @param key      the key to store
-+     * @param value    the value to store
-+     * @return the newly created entry
-+     */
-+    protected HashEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
-+        return new HashEntry<K, V>(next, hashCode, key, value);
-+    }
-+
-+    /**
-+     * Adds an entry into this map.
-+     * <p/>
-+     * This implementation adds the entry to the data storage table.
-+     * Subclasses could override to handle changes to the map.
-+     *
-+     * @param entry     the entry to add
-+     * @param hashIndex the index into the data array to store at
-+     */
-+    protected void addEntry(HashEntry<K, V> entry, int hashIndex) {
-+        data[hashIndex] = entry;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Removes a mapping from the map.
-+     * <p/>
-+     * This implementation calls <code>removeEntry()</code> and <code>destroyEntry()</code>.
-+     * It also handles changes to <code>modCount</code> and <code>size</code>.
-+     * Subclasses could override to fully control removals from the map.
-+     *
-+     * @param entry     the entry to remove
-+     * @param hashIndex the index into the data structure
-+     * @param previous  the previous entry in the chain
-+     */
-+    protected void removeMapping(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) {
-+        modCount++;
-+        removeEntry(entry, hashIndex, previous);
-+        size--;
-+        destroyEntry(entry);
-+    }
-+
-+    /**
-+     * Removes an entry from the chain stored in a particular index.
-+     * <p/>
-+     * This implementation removes the entry from the data storage table.
-+     * The size is not updated.
-+     * Subclasses could override to handle changes to the map.
-+     *
-+     * @param entry     the entry to remove
-+     * @param hashIndex the index into the data structure
-+     * @param previous  the previous entry in the chain
-+     */
-+    protected void removeEntry(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) {
-+        if (previous == null) {
-+            data[hashIndex] = entry.next;
-+        } else {
-+            previous.next = entry.next;
-+        }
-+    }
-+
-+    /**
-+     * Kills an entry ready for the garbage collector.
-+     * <p/>
-+     * This implementation prepares the HashEntry for garbage collection.
-+     * Subclasses can override this to implement caching (override clear as well).
-+     *
-+     * @param entry the entry to destroy
-+     */
-+    protected void destroyEntry(HashEntry<K, V> entry) {
-+        entry.next = null;
-+        entry.key = null;
-+        entry.value = null;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks the capacity of the map and enlarges it if necessary.
-+     * <p/>
-+     * This implementation uses the threshold to check if the map needs enlarging
-+     */
-+    protected void checkCapacity() {
-+        if (size >= threshold) {
-+            int newCapacity = data.length * 2;
-+            if (newCapacity <= MAXIMUM_CAPACITY) {
-+                ensureCapacity(newCapacity);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Changes the size of the data structure to the capacity proposed.
-+     *
-+     * @param newCapacity the new capacity of the array (a power of two, less or equal to max)
-+     */
-+    protected void ensureCapacity(int newCapacity) {
-+        int oldCapacity = data.length;
-+        if (newCapacity <= oldCapacity) {
-+            return;
-+        }
-+        if (size == 0) {
-+            threshold = calculateThreshold(newCapacity, loadFactor);
-+            data = new HashEntry[newCapacity];
-+        } else {
-+            HashEntry<K, V> oldEntries[] = data;
-+            HashEntry<K, V> newEntries[] = new HashEntry[newCapacity];
-+
-+            modCount++;
-+            for (int i = oldCapacity - 1; i >= 0; i--) {
-+                HashEntry<K, V> entry = oldEntries[i];
-+                if (entry != null) {
-+                    oldEntries[i] = null;  // gc
-+                    do {
-+                        HashEntry<K, V> next = entry.next;
-+                        int index = hashIndex(entry.hashCode, newCapacity);
-+                        entry.next = newEntries[index];
-+                        newEntries[index] = entry;
-+                        entry = next;
-+                    } while (entry != null);
-+                }
-+            }
-+            threshold = calculateThreshold(newCapacity, loadFactor);
-+            data = newEntries;
-+        }
-+    }
-+
-+    /**
-+     * Calculates the new capacity of the map.
-+     * This implementation normalizes the capacity to a power of two.
-+     *
-+     * @param proposedCapacity the proposed capacity
-+     * @return the normalized new capacity
-+     */
-+    protected int calculateNewCapacity(int proposedCapacity) {
-+        int newCapacity = 1;
-+        if (proposedCapacity > MAXIMUM_CAPACITY) {
-+            newCapacity = MAXIMUM_CAPACITY;
-+        } else {
-+            while (newCapacity < proposedCapacity) {
-+                newCapacity <<= 1;  // multiply by two
-+            }
-+            if (newCapacity > MAXIMUM_CAPACITY) {
-+                newCapacity = MAXIMUM_CAPACITY;
-+            }
-+        }
-+        return newCapacity;
-+    }
-+
-+    /**
-+     * Calculates the new threshold of the map, where it will be resized.
-+     * This implementation uses the load factor.
-+     *
-+     * @param newCapacity the new capacity
-+     * @param factor      the load factor
-+     * @return the new resize threshold
-+     */
-+    protected int calculateThreshold(int newCapacity, float factor) {
-+        return (int) (newCapacity * factor);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the <code>next</code> field from a <code>HashEntry</code>.
-+     * Used in subclasses that have no visibility of the field.
-+     *
-+     * @param entry the entry to query, must not be null
-+     * @return the <code>next</code> field of the entry
-+     * @throws NullPointerException if the entry is null
-+     * @since Commons Collections 3.1
-+     */
-+    protected HashEntry<K, V> entryNext(HashEntry<K, V> entry) {
-+        return entry.next;
-+    }
-+
-+    /**
-+     * Gets the <code>hashCode</code> field from a <code>HashEntry</code>.
-+     * Used in subclasses that have no visibility of the field.
-+     *
-+     * @param entry the entry to query, must not be null
-+     * @return the <code>hashCode</code> field of the entry
-+     * @throws NullPointerException if the entry is null
-+     * @since Commons Collections 3.1
-+     */
-+    protected int entryHashCode(HashEntry<K, V> entry) {
-+        return entry.hashCode;
-+    }
-+
-+    /**
-+     * Gets the <code>key</code> field from a <code>HashEntry</code>.
-+     * Used in subclasses that have no visibility of the field.
-+     *
-+     * @param entry the entry to query, must not be null
-+     * @return the <code>key</code> field of the entry
-+     * @throws NullPointerException if the entry is null
-+     * @since Commons Collections 3.1
-+     */
-+    protected K entryKey(HashEntry<K, V> entry) {
-+        return entry.key;
-+    }
-+
-+    /**
-+     * Gets the <code>value</code> field from a <code>HashEntry</code>.
-+     * Used in subclasses that have no visibility of the field.
-+     *
-+     * @param entry the entry to query, must not be null
-+     * @return the <code>value</code> field of the entry
-+     * @throws NullPointerException if the entry is null
-+     * @since Commons Collections 3.1
-+     */
-+    protected V entryValue(HashEntry<K, V> entry) {
-+        return entry.value;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator over the map.
-+     * Changes made to the iterator affect this map.
-+     * <p/>
-+     * A MapIterator returns the keys in the map. It also provides convenient
-+     * methods to get the key and value, and set the value.
-+     * It avoids the need to create an entrySet/keySet/values object.
-+     * It also avoids creating the Map.Entry object.
-+     *
-+     * @return the map iterator
-+     */
-+    public MapIterator<K, V> mapIterator() {
-+        if (size == 0) {
-+            return EmptyMapIterator.INSTANCE;
-+        }
-+        return new HashMapIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * MapIterator implementation.
-+     */
-+    protected static class HashMapIterator <K,V> extends HashIterator<K, V> implements MapIterator<K, V> {
-+
-+        protected HashMapIterator(AbstractHashedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public K next() {
-+            return super.nextEntry().getKey();
-+        }
-+
-+        public K getKey() {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
-+            }
-+            return current.getKey();
-+        }
-+
-+        public V getValue() {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
-+            }
-+            return current.getValue();
-+        }
-+
-+        public V setValue(V value) {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
-+            }
-+            return current.setValue(value);
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Gets the entrySet view of the map.
-+     * Changes made to the view affect this map.
-+     * To simply iterate through the entries, use {@link #mapIterator()}.
-+     *
-+     * @return the entrySet view
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        if (entrySet == null) {
-+            entrySet = new EntrySet<K, V>(this);
-+        }
-+        return entrySet;
-+    }
-+
-+    /**
-+     * Creates an entry set iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @return the entrySet iterator
-+     */
-+    protected Iterator<Map.Entry<K, V>> createEntrySetIterator() {
-+        if (size() == 0) {
-+            return EmptyIterator.INSTANCE;
-+        }
-+        return new EntrySetIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * EntrySet implementation.
-+     */
-+    protected static class EntrySet <K,V> extends AbstractSet<Map.Entry<K, V>> {
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractHashedMap<K, V> parent;
-+
-+        protected EntrySet(AbstractHashedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return parent.size();
-+        }
-+
-+        public void clear() {
-+            parent.clear();
-+        }
-+
-+        public boolean contains(Map.Entry<K, V> entry) {
-+            Map.Entry<K, V> e = entry;
-+            Entry<K, V> match = parent.getEntry(e.getKey());
-+            return (match != null && match.equals(e));
-+        }
-+
-+        public boolean remove(Object obj) {
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            if (contains(obj) == false) {
-+                return false;
-+            }
-+            Map.Entry<K, V> entry = (Map.Entry<K, V>) obj;
-+            K key = entry.getKey();
-+            parent.remove(key);
-+            return true;
-+        }
-+
-+        public Iterator<Map.Entry<K, V>> iterator() {
-+            return parent.createEntrySetIterator();
-+        }
-+    }
-+
-+    /**
-+     * EntrySet iterator.
-+     */
-+    protected static class EntrySetIterator <K,V> extends HashIterator<K, V> implements Iterator<Map.Entry<K, V>> {
-+
-+        protected EntrySetIterator(AbstractHashedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public HashEntry<K, V> next() {
-+            return super.nextEntry();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Gets the keySet view of the map.
-+     * Changes made to the view affect this map.
-+     * To simply iterate through the keys, use {@link #mapIterator()}.
-+     *
-+     * @return the keySet view
-+     */
-+    public Set<K> keySet() {
-+        if (keySet == null) {
-+            keySet = new KeySet<K, V>(this);
-+        }
-+        return keySet;
-+    }
-+
-+    /**
-+     * Creates a key set iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @return the keySet iterator
-+     */
-+    protected Iterator<K> createKeySetIterator() {
-+        if (size() == 0) {
-+            return EmptyIterator.INSTANCE;
-+        }
-+        return new KeySetIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * KeySet implementation.
-+     */
-+    protected static class KeySet <K,V> extends AbstractSet<K> {
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractHashedMap<K, V> parent;
-+
-+        protected KeySet(AbstractHashedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return parent.size();
-+        }
-+
-+        public void clear() {
-+            parent.clear();
-+        }
-+
-+        public boolean contains(Object key) {
-+            return parent.containsKey(key);
-+        }
-+
-+        public boolean remove(Object key) {
-+            boolean result = parent.containsKey(key);
-+            parent.remove(key);
-+            return result;
-+        }
-+
-+        public Iterator<K> iterator() {
-+            return parent.createKeySetIterator();
-+        }
-+    }
-+
-+    /**
-+     * KeySet iterator.
-+     */
-+    protected static class KeySetIterator <K,V> extends HashIterator<K, V> implements Iterator<K> {
-+
-+        protected KeySetIterator(AbstractHashedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public K next() {
-+            return super.nextEntry().getKey();
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Gets the values view of the map.
-+     * Changes made to the view affect this map.
-+     * To simply iterate through the values, use {@link #mapIterator()}.
-+     *
-+     * @return the values view
-+     */
-+    public Collection<V> values() {
-+        if (values == null) {
-+            values = new Values(this);
-+        }
-+        return values;
-+    }
-+
-+    /**
-+     * Creates a values iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @return the values iterator
-+     */
-+    protected Iterator<V> createValuesIterator() {
-+        if (size() == 0) {
-+            return EmptyIterator.INSTANCE;
-+        }
-+        return new ValuesIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Values implementation.
-+     */
-+    protected static class Values <K,V> extends AbstractCollection<V> {
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractHashedMap<K, V> parent;
-+
-+        protected Values(AbstractHashedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return parent.size();
-+        }
-+
-+        public void clear() {
-+            parent.clear();
-+        }
-+
-+        public boolean contains(Object value) {
-+            return parent.containsValue(value);
-+        }
-+
-+        public Iterator<V> iterator() {
-+            return parent.createValuesIterator();
-+        }
-+    }
-+
-+    /**
-+     * Values iterator.
-+     */
-+    protected static class ValuesIterator <K,V> extends HashIterator<K, V> implements Iterator<V> {
-+
-+        protected ValuesIterator(AbstractHashedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public V next() {
-+            return super.nextEntry().getValue();
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * HashEntry used to store the data.
-+     * <p/>
-+     * If you subclass <code>AbstractHashedMap</code> but not <code>HashEntry</code>
-+     * then you will not be able to access the protected fields.
-+     * The <code>entryXxx()</code> methods on <code>AbstractHashedMap</code> exist
-+     * to provide the necessary access.
-+     */
-+    protected static class HashEntry <K,V> implements Map.Entry<K, V>, KeyValue<K, V> {
-+        /**
-+         * The next entry in the hash chain
-+         */
-+        protected HashEntry<K, V> next;
-+        /**
-+         * The hash code of the key
-+         */
-+        protected int hashCode;
-+        /**
-+         * The key
-+         */
-+        private K key;
-+        /**
-+         * The value
-+         */
-+        private V value;
-+
-+        protected HashEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
-+            super();
-+            this.next = next;
-+            this.hashCode = hashCode;
-+            this.key = key;
-+            this.value = value;
-+        }
-+
-+        public K getKey() {
-+            return key;
-+        }
-+
-+        public void setKey(K key) {
-+            this.key = key;
-+        }
-+
-+        public V getValue() {
-+            return value;
-+        }
-+
-+        public V setValue(V value) {
-+            V old = this.value;
-+            this.value = value;
-+            return old;
-+        }
-+
-+        public boolean equals(Object obj) {
-+            if (obj == this) {
-+                return true;
-+            }
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry other = (Map.Entry) obj;
-+            return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) && (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
-+        }
-+
-+        public int hashCode() {
-+            return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode());
-+        }
-+
-+        public String toString() {
-+            return new StringBuffer().append(getKey()).append('=').append(getValue()).toString();
-+        }
-+    }
-+
-+    /**
-+     * Base Iterator
-+     */
-+    protected static abstract class HashIterator <K,V> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractHashedMap parent;
-+        /**
-+         * The current index into the array of buckets
-+         */
-+        protected int hashIndex;
-+        /**
-+         * The last returned entry
-+         */
-+        protected HashEntry<K, V> last;
-+        /**
-+         * The next entry
-+         */
-+        protected HashEntry<K, V> next;
-+        /**
-+         * The modification count expected
-+         */
-+        protected int expectedModCount;
-+
-+        protected HashIterator(AbstractHashedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+            HashEntry<K, V>[] data = parent.data;
-+            int i = data.length;
-+            HashEntry<K, V> next = null;
-+            while (i > 0 && next == null) {
-+                next = data[--i];
-+            }
-+            this.next = next;
-+            this.hashIndex = i;
-+            this.expectedModCount = parent.modCount;
-+        }
-+
-+        public boolean hasNext() {
-+            return (next != null);
-+        }
-+
-+        protected HashEntry<K, V> nextEntry() {
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+            HashEntry<K, V> newCurrent = next;
-+            if (newCurrent == null) {
-+                throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
-+            }
-+            HashEntry<K, V>[] data = parent.data;
-+            int i = hashIndex;
-+            HashEntry<K, V> n = newCurrent.next;
-+            while (n == null && i > 0) {
-+                n = data[--i];
-+            }
-+            next = n;
-+            hashIndex = i;
-+            last = newCurrent;
-+            return newCurrent;
-+        }
-+
-+        protected HashEntry<K, V> currentEntry() {
-+            return last;
-+        }
-+
-+        public void remove() {
-+            if (last == null) {
-+                throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
-+            }
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+            parent.remove(last.getKey());
-+            last = null;
-+            expectedModCount = parent.modCount;
-+        }
-+
-+        public String toString() {
-+            if (last != null) {
-+                return "Iterator[" + last.getKey() + "=" + last.getValue() + "]";
-+            } else {
-+                return "Iterator[]";
-+            }
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Writes the map data to the stream. This method must be overridden if a
-+     * subclass must be setup before <code>put()</code> is used.
-+     * <p/>
-+     * Serialization is not one of the JDK's nicest topics. Normal serialization will
-+     * initialise the superclass before the subclass. Sometimes however, this isn't
-+     * what you want, as in this case the <code>put()</code> method on read can be
-+     * affected by subclass state.
-+     * <p/>
-+     * The solution adopted here is to serialize the state data of this class in
-+     * this protected method. This method must be called by the
-+     * <code>writeObject()</code> of the first serializable subclass.
-+     * <p/>
-+     * Subclasses may override if they have a specific field that must be present
-+     * on read before this implementation will work. Generally, the read determines
-+     * what must be serialized here, if anything.
-+     *
-+     * @param out the output stream
-+     */
-+    protected void doWriteObject(ObjectOutputStream out) throws IOException {
-+        out.writeFloat(loadFactor);
-+        out.writeInt(data.length);
-+        out.writeInt(size);
-+        for (MapIterator it = mapIterator(); it.hasNext();) {
-+            out.writeObject(it.next());
-+            out.writeObject(it.getValue());
-+        }
-+    }
-+
-+    /**
-+     * Reads the map data from the stream. This method must be overridden if a
-+     * subclass must be setup before <code>put()</code> is used.
-+     * <p/>
-+     * Serialization is not one of the JDK's nicest topics. Normal serialization will
-+     * initialise the superclass before the subclass. Sometimes however, this isn't
-+     * what you want, as in this case the <code>put()</code> method on read can be
-+     * affected by subclass state.
-+     * <p/>
-+     * The solution adopted here is to deserialize the state data of this class in
-+     * this protected method. This method must be called by the
-+     * <code>readObject()</code> of the first serializable subclass.
-+     * <p/>
-+     * Subclasses may override if the subclass has a specific field that must be present
-+     * before <code>put()</code> or <code>calculateThreshold()</code> will work correctly.
-+     *
-+     * @param in the input stream
-+     */
-+    protected void doReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        loadFactor = in.readFloat();
-+        int capacity = in.readInt();
-+        int size = in.readInt();
-+        init();
-+        data = new HashEntry[capacity];
-+        for (int i = 0; i < size; i++) {
-+            K key = (K) in.readObject();
-+            V value = (V) in.readObject();
-+            put(key, value);
-+        }
-+        threshold = calculateThreshold(data.length, loadFactor);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     * <p/>
-+     * To implement <code>clone()</code>, a subclass must implement the
-+     * <code>Cloneable</code> interface and make this method public.
-+     *
-+     * @return a shallow clone
-+     */
-+    protected Object clone() {
-+        try {
-+            AbstractHashedMap cloned = (AbstractHashedMap) super.clone();
-+            cloned.data = new HashEntry[data.length];
-+            cloned.entrySet = null;
-+            cloned.keySet = null;
-+            cloned.values = null;
-+            cloned.modCount = 0;
-+            cloned.size = 0;
-+            cloned.init();
-+            cloned.putAll(this);
-+            return cloned;
-+
-+        } catch (CloneNotSupportedException ex) {
-+            return null;  // should never happen
-+        }
-+    }
-+
-+    /**
-+     * Compares this map with another.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof Map == false) {
-+            return false;
-+        }
-+        Map map = (Map) obj;
-+        if (map.size() != size()) {
-+            return false;
-+        }
-+        MapIterator it = mapIterator();
-+        try {
-+            while (it.hasNext()) {
-+                Object key = it.next();
-+                Object value = it.getValue();
-+                if (value == null) {
-+                    if (map.get(key) != null || map.containsKey(key) == false) {
-+                        return false;
-+                    }
-+                } else {
-+                    if (value.equals(map.get(key)) == false) {
-+                        return false;
-+                    }
-+                }
-+            }
-+        } catch (ClassCastException ignored) {
-+            return false;
-+        } catch (NullPointerException ignored) {
-+            return false;
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Gets the standard Map hashCode.
-+     *
-+     * @return the hash code defined in the Map interface
-+     */
-+    public int hashCode() {
-+        int total = 0;
-+        Iterator it = createEntrySetIterator();
-+        while (it.hasNext()) {
-+            total += it.next().hashCode();
-+        }
-+        return total;
-+    }
-+
-+    /**
-+     * Gets the map as a String.
-+     *
-+     * @return a string version of the map
-+     */
-+    public String toString() {
-+        if (size() == 0) {
-+            return "{}";
-+        }
-+        StringBuffer buf = new StringBuffer(32 * size());
-+        buf.append('{');
-+
-+        MapIterator it = mapIterator();
-+        boolean hasNext = it.hasNext();
-+        while (hasNext) {
-+            Object key = it.next();
-+            Object value = it.getValue();
-+            buf.append(key == this ? "(this Map)" : key).append('=').append(value == this ? "(this Map)" : value);
-+
-+            hasNext = it.hasNext();
-+            if (hasNext) {
-+                buf.append(',').append(' ');
-+            }
-+        }
-+
-+        buf.append('}');
-+        return buf.toString();
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/AbstractInputCheckedMapDecorator.java
-@@ -0,0 +1,199 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.iterators.AbstractIteratorDecorator;
-+import org.apache.commons.collections15.keyvalue.AbstractMapEntryDecorator;
-+import org.apache.commons.collections15.set.AbstractSetDecorator;
-+
-+import java.lang.reflect.Array;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * An abstract base class that simplifies the task of creating map decorators.
-+ * <p/>
-+ * The Map API is very difficult to decorate correctly, and involves implementing
-+ * lots of different classes. This class exists to provide a simpler API.
-+ * <p/>
-+ * Special hook methods are provided that are called when objects are added to
-+ * the map. By overriding these methods, the input can be validated or manipulated.
-+ * In addition to the main map methods, the entrySet is also affected, which is
-+ * the hardest part of writing map implementations.
-+ * <p/>
-+ * This class is package-scoped, and may be withdrawn or replaced in future
-+ * versions of Commons Collections.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.1
-+ */
-+abstract class AbstractInputCheckedMapDecorator <K,V> extends AbstractMapDecorator<K, V> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     */
-+    protected AbstractInputCheckedMapDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    protected AbstractInputCheckedMapDecorator(Map<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Hook method called when a value is being set using <code>setValue</code>.
-+     * <p/>
-+     * An implementation may validate the value and throw an exception
-+     * or it may transform the value into another object.
-+     * <p/>
-+     * This implementation returns the input value.
-+     *
-+     * @param value the value to check
-+     * @throws UnsupportedOperationException if the map may not be changed by setValue
-+     * @throws IllegalArgumentException      if the specified value is invalid
-+     * @throws ClassCastException            if the class of the specified value is invalid
-+     * @throws NullPointerException          if the specified value is null and nulls are invalid
-+     */
-+    protected abstract V checkSetValue(V value);
-+
-+    /**
-+     * Hook method called to determine if <code>checkSetValue</code> has any effect.
-+     * <p/>
-+     * An implementation should return false if the <code>checkSetValue</code> method
-+     * has no effect as this optimises the implementation.
-+     * <p/>
-+     * This implementation returns <code>true</code>.
-+     */
-+    protected boolean isSetValueChecking() {
-+        return true;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        if (isSetValueChecking()) {
-+            return new EntrySet<K, V>(map.entrySet(), this);
-+        } else {
-+            return map.entrySet();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implementation of an entry set that checks additions via setValue.
-+     */
-+    static class EntrySet <K,V> extends AbstractSetDecorator<Map.Entry<K, V>> {
-+
-+        /**
-+         * The parent map
-+         */
-+        private final AbstractInputCheckedMapDecorator<K, V> parent;
-+
-+        protected EntrySet(Set<Map.Entry<K, V>> set, AbstractInputCheckedMapDecorator<K, V> parent) {
-+            super(set);
-+            this.parent = parent;
-+        }
-+
-+        public Iterator<Map.Entry<K, V>> iterator() {
-+            return new EntrySetIterator<K, V>(collection.iterator(), parent);
-+        }
-+
-+        public Object[] toArray() {
-+            Object[] array = collection.toArray();
-+            for (int i = 0; i < array.length; i++) {
-+                array[i] = new MapEntry((Map.Entry) array[i], parent);
-+            }
-+            return array;
-+        }
-+
-+        public <T> T[] toArray(T array[]) {
-+            Object[] result = array;
-+            if (array.length > 0) {
-+                // we must create a new array to handle multi-threaded situations
-+                // where another thread could access data before we decorate it
-+                result = (T[]) Array.newInstance(array.getClass().getComponentType(), 0);
-+            }
-+            result = collection.toArray(result);
-+            for (int i = 0; i < result.length; i++) {
-+                result[i] = new MapEntry((Map.Entry) result[i], parent);
-+            }
-+
-+            // check to see if result should be returned straight
-+            if (result.length > array.length) {
-+                return (T[]) result;
-+            }
-+
-+            // copy back into input array to fulfil the method contract
-+            System.arraycopy(result, 0, array, 0, result.length);
-+            if (array.length > result.length) {
-+                array[result.length] = null;
-+            }
-+            return (T[]) array;
-+        }
-+    }
-+
-+    /**
-+     * Implementation of an entry set iterator that checks additions via setValue.
-+     */
-+    static class EntrySetIterator <K,V> extends AbstractIteratorDecorator<Map.Entry<K, V>> {
-+
-+        /**
-+         * The parent map
-+         */
-+        private final AbstractInputCheckedMapDecorator<K, V> parent;
-+
-+        protected EntrySetIterator(Iterator<Map.Entry<K, V>> iterator, AbstractInputCheckedMapDecorator<K, V> parent) {
-+            super(iterator);
-+            this.parent = parent;
-+        }
-+
-+        public Map.Entry<K, V> next() {
-+            Map.Entry<K, V> entry = iterator.next();
-+            return new MapEntry<K, V>(entry, parent);
-+        }
-+    }
-+
-+    /**
-+     * Implementation of a map entry that checks additions via setValue.
-+     */
-+    static class MapEntry <K,V> extends AbstractMapEntryDecorator<K, V> {
-+
-+        /**
-+         * The parent map
-+         */
-+        private final AbstractInputCheckedMapDecorator<K, V> parent;
-+
-+        protected MapEntry(Map.Entry<K, V> entry, AbstractInputCheckedMapDecorator<K, V> parent) {
-+            super(entry);
-+            this.parent = parent;
-+        }
-+
-+        public V setValue(V value) {
-+            value = parent.checkSetValue(value);
-+            return entry.setValue(value);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/AbstractLinkedMap.java
-@@ -0,0 +1,617 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.*;
-+import org.apache.commons.collections15.iterators.EmptyOrderedIterator;
-+import org.apache.commons.collections15.iterators.EmptyOrderedMapIterator;
-+
-+import java.util.ConcurrentModificationException;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.NoSuchElementException;
-+
-+/**
-+ * An abstract implementation of a hash-based map that links entries to create an
-+ * ordered map and which provides numerous points for subclasses to override.
-+ * <p/>
-+ * This class implements all the features necessary for a subclass linked
-+ * hash-based map. Key-value entries are stored in instances of the
-+ * <code>LinkEntry</code> class which can be overridden and replaced.
-+ * The iterators can similarly be replaced, without the need to replace the KeySet,
-+ * EntrySet and Values view classes.
-+ * <p/>
-+ * Overridable methods are provided to change the default hashing behaviour, and
-+ * to change how entries are added to and removed from the map. Hopefully, all you
-+ * need for unusual subclasses is here.
-+ * <p/>
-+ * This implementation maintains order by original insertion, but subclasses
-+ * may work differently. The <code>OrderedMap</code> interface is implemented
-+ * to provide access to bidirectional iteration and extra convenience methods.
-+ * <p/>
-+ * The <code>orderedMapIterator()</code> method provides direct access to a
-+ * bidirectional iterator. The iterators from the other views can also be cast
-+ * to <code>OrderedIterator</code> if required.
-+ * <p/>
-+ * All the available iterators can be reset back to the start by casting to
-+ * <code>ResettableIterator</code> and calling <code>reset()</code>.
-+ * <p/>
-+ * The implementation is also designed to be subclassed, with lots of useful
-+ * methods exposed.
-+ *
-+ * @author java util LinkedHashMap
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class AbstractLinkedMap <K,V> extends AbstractHashedMap<K, V> implements OrderedMap<K, V> {
-+
-+    /**
-+     * Header in the linked list
-+     */
-+    protected transient LinkEntry<K, V> header;
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     */
-+    protected AbstractLinkedMap() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor which performs no validation on the passed in parameters.
-+     *
-+     * @param initialCapacity the initial capacity, must be a power of two
-+     * @param loadFactor      the load factor, must be > 0.0f and generally < 1.0f
-+     * @param threshold       the threshold, must be sensible
-+     */
-+    protected AbstractLinkedMap(int initialCapacity, float loadFactor, int threshold) {
-+        super(initialCapacity, loadFactor, threshold);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     */
-+    protected AbstractLinkedMap(int initialCapacity) {
-+        super(initialCapacity);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @param loadFactor      the load factor
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     * @throws IllegalArgumentException if the load factor is less than zero
-+     */
-+    protected AbstractLinkedMap(int initialCapacity, float loadFactor) {
-+        super(initialCapacity, loadFactor);
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException if the map is null
-+     */
-+    protected AbstractLinkedMap(Map<? extends K, ? extends V> map) {
-+        super(map);
-+    }
-+
-+    /**
-+     * Initialise this subclass during construction.
-+     */
-+    protected void init() {
-+        header = new LinkEntry<K, V>(null, -1, null, null);
-+        header.before = header.after = header;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks whether the map contains the specified value.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the value
-+     */
-+    public boolean containsValue(Object value) {
-+        // override uses faster iterator
-+        if (value == null) {
-+            for (LinkEntry entry = header.after; entry != header; entry = entry.after) {
-+                if (entry.getValue() == null) {
-+                    return true;
-+                }
-+            }
-+        } else {
-+            for (LinkEntry entry = header.after; entry != header; entry = entry.after) {
-+                if (isEqualValue(value, entry.getValue())) {
-+                    return true;
-+                }
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Clears the map, resetting the size to zero and nullifying references
-+     * to avoid garbage collection issues.
-+     */
-+    public void clear() {
-+        // override to reset the linked list
-+        super.clear();
-+        header.before = header.after = header;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the first key in the map, which is the most recently inserted.
-+     *
-+     * @return the most recently inserted key
-+     */
-+    public K firstKey() {
-+        if (size == 0) {
-+            throw new NoSuchElementException("Map is empty");
-+        }
-+        return header.after.getKey();
-+    }
-+
-+    /**
-+     * Gets the last key in the map, which is the first inserted.
-+     *
-+     * @return the eldest key
-+     */
-+    public K lastKey() {
-+        if (size == 0) {
-+            throw new NoSuchElementException("Map is empty");
-+        }
-+        return header.before.getKey();
-+    }
-+
-+    /**
-+     * Gets the next key in sequence.
-+     *
-+     * @param key the key to get after
-+     * @return the next key
-+     */
-+    public K nextKey(K key) {
-+        LinkEntry<K, V> entry = (LinkEntry<K, V>) getEntry(key);
-+        return (entry == null || entry.after == header ? null : entry.after.getKey());
-+    }
-+
-+    /**
-+     * Gets the previous key in sequence.
-+     *
-+     * @param key the key to get before
-+     * @return the previous key
-+     */
-+    public K previousKey(K key) {
-+        LinkEntry<K, V> entry = (LinkEntry<K, V>) getEntry(key);
-+        return (entry == null || entry.before == header ? null : entry.before.getKey());
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Gets the key at the specified index.
-+     *
-+     * @param index the index to retrieve
-+     * @return the key at the specified index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    protected LinkEntry<K, V> getEntry(int index) {
-+        if (index < 0) {
-+            throw new IndexOutOfBoundsException("Index " + index + " is less than zero");
-+        }
-+        if (index >= size) {
-+            throw new IndexOutOfBoundsException("Index " + index + " is invalid for size " + size);
-+        }
-+        LinkEntry<K, V> entry;
-+        if (index < (size / 2)) {
-+            // Search forwards
-+            entry = header.after;
-+            for (int currentIndex = 0; currentIndex < index; currentIndex++) {
-+                entry = entry.after;
-+            }
-+        } else {
-+            // Search backwards
-+            entry = header;
-+            for (int currentIndex = size; currentIndex > index; currentIndex--) {
-+                entry = entry.before;
-+            }
-+        }
-+        return entry;
-+    }
-+
-+    /**
-+     * Adds an entry into this map, maintaining insertion order.
-+     * <p/>
-+     * This implementation adds the entry to the data storage table and
-+     * to the end of the linked list.
-+     *
-+     * @param entry     the entry to add
-+     * @param hashIndex the index into the data array to store at
-+     */
-+    protected void addEntry(HashEntry<K, V> entry, int hashIndex) {
-+        LinkEntry<K, V> link = (LinkEntry<K, V>) entry;
-+        link.after = header;
-+        link.before = header.before;
-+        header.before.after = link;
-+        header.before = link;
-+        data[hashIndex] = entry;
-+    }
-+
-+    /**
-+     * Creates an entry to store the data.
-+     * <p/>
-+     * This implementation creates a new LinkEntry instance.
-+     *
-+     * @param next     the next entry in sequence
-+     * @param hashCode the hash code to use
-+     * @param key      the key to store
-+     * @param value    the value to store
-+     * @return the newly created entry
-+     */
-+    protected HashEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
-+        return new LinkEntry<K, V>(next, hashCode, key, value);
-+    }
-+
-+    /**
-+     * Removes an entry from the map and the linked list.
-+     * <p/>
-+     * This implementation removes the entry from the linked list chain, then
-+     * calls the superclass implementation.
-+     *
-+     * @param entry     the entry to remove
-+     * @param hashIndex the index into the data structure
-+     * @param previous  the previous entry in the chain
-+     */
-+    protected void removeEntry(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) {
-+        LinkEntry<K, V> link = (LinkEntry<K, V>) entry;
-+        link.before.after = link.after;
-+        link.after.before = link.before;
-+        link.after = null;
-+        link.before = null;
-+        super.removeEntry(entry, hashIndex, previous);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the <code>before</code> field from a <code>LinkEntry</code>.
-+     * Used in subclasses that have no visibility of the field.
-+     *
-+     * @param entry the entry to query, must not be null
-+     * @return the <code>before</code> field of the entry
-+     * @throws NullPointerException if the entry is null
-+     * @since Commons Collections 3.1
-+     */
-+    protected LinkEntry<K, V> entryBefore(LinkEntry<K, V> entry) {
-+        return entry.before;
-+    }
-+
-+    /**
-+     * Gets the <code>after</code> field from a <code>LinkEntry</code>.
-+     * Used in subclasses that have no visibility of the field.
-+     *
-+     * @param entry the entry to query, must not be null
-+     * @return the <code>after</code> field of the entry
-+     * @throws NullPointerException if the entry is null
-+     * @since Commons Collections 3.1
-+     */
-+    protected LinkEntry<K, V> entryAfter(LinkEntry<K, V> entry) {
-+        return entry.after;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator over the map.
-+     * Changes made to the iterator affect this map.
-+     * <p/>
-+     * A MapIterator returns the keys in the map. It also provides convenient
-+     * methods to get the key and value, and set the value.
-+     * It avoids the need to create an entrySet/keySet/values object.
-+     *
-+     * @return the map iterator
-+     */
-+    public MapIterator<K, V> mapIterator() {
-+        if (size == 0) {
-+            return EmptyOrderedMapIterator.INSTANCE;
-+        }
-+        return new LinkMapIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Gets a bidirectional iterator over the map.
-+     * Changes made to the iterator affect this map.
-+     * <p/>
-+     * A MapIterator returns the keys in the map. It also provides convenient
-+     * methods to get the key and value, and set the value.
-+     * It avoids the need to create an entrySet/keySet/values object.
-+     *
-+     * @return the map iterator
-+     */
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        if (size == 0) {
-+            return EmptyOrderedMapIterator.INSTANCE;
-+        }
-+        return new LinkMapIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * MapIterator implementation.
-+     */
-+    protected static class LinkMapIterator <K,V> extends LinkIterator<K, V> implements OrderedMapIterator<K, V>, OrderedIterator<K>, ResettableIterator<K> {
-+
-+        protected LinkMapIterator(AbstractLinkedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public K next() {
-+            return super.nextEntry().getKey();
-+        }
-+
-+        public K previous() {
-+            return super.previousEntry().getKey();
-+        }
-+
-+        public K getKey() {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
-+            }
-+            return current.getKey();
-+        }
-+
-+        public V getValue() {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
-+            }
-+            return current.getValue();
-+        }
-+
-+        public V setValue(V value) {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
-+            }
-+            return current.setValue(value);
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Creates an entry set iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @return the entrySet iterator
-+     */
-+    protected Iterator<Map.Entry<K, V>> createEntrySetIterator() {
-+        if (size() == 0) {
-+            return EmptyOrderedIterator.INSTANCE;
-+        }
-+        return new EntrySetIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * EntrySet iterator.
-+     */
-+    protected static class EntrySetIterator <K,V> extends LinkIterator<K, V> implements OrderedIterator<Map.Entry<K, V>>, ResettableIterator<Map.Entry<K, V>> {
-+
-+        protected EntrySetIterator(AbstractLinkedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public Map.Entry<K, V> next() {
-+            return super.nextEntry();
-+        }
-+
-+        public Map.Entry<K, V> previous() {
-+            return super.previousEntry();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Creates a key set iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @return the keySet iterator
-+     */
-+    protected Iterator createKeySetIterator() {
-+        if (size() == 0) {
-+            return EmptyOrderedIterator.INSTANCE;
-+        }
-+        return new KeySetIterator(this);
-+    }
-+
-+    /**
-+     * KeySet iterator.
-+     */
-+    protected static class KeySetIterator <K,V> extends LinkIterator<K, V> implements OrderedIterator<K>, ResettableIterator<K> {
-+
-+        protected KeySetIterator(AbstractLinkedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public K next() {
-+            return super.nextEntry().getKey();
-+        }
-+
-+        public K previous() {
-+            return super.previousEntry().getKey();
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Creates a values iterator.
-+     * Subclasses can override this to return iterators with different properties.
-+     *
-+     * @return the values iterator
-+     */
-+    protected Iterator<V> createValuesIterator() {
-+        if (size() == 0) {
-+            return EmptyOrderedIterator.INSTANCE;
-+        }
-+        return new ValuesIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Values iterator.
-+     */
-+    protected static class ValuesIterator <K,V> extends LinkIterator<K, V> implements OrderedIterator<V>, ResettableIterator<V> {
-+
-+        protected ValuesIterator(AbstractLinkedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public V next() {
-+            return super.nextEntry().getValue();
-+        }
-+
-+        public V previous() {
-+            return super.previousEntry().getValue();
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * LinkEntry that stores the data.
-+     * <p/>
-+     * If you subclass <code>AbstractLinkedMap</code> but not <code>LinkEntry</code>
-+     * then you will not be able to access the protected fields.
-+     * The <code>entryXxx()</code> methods on <code>AbstractLinkedMap</code> exist
-+     * to provide the necessary access.
-+     */
-+    protected static class LinkEntry <K,V> extends HashEntry<K, V> {
-+        /**
-+         * The entry before this one in the order
-+         */
-+        protected LinkEntry<K, V> before;
-+        /**
-+         * The entry after this one in the order
-+         */
-+        protected LinkEntry<K, V> after;
-+
-+        /**
-+         * Constructs a new entry.
-+         *
-+         * @param next     the next entry in the hash bucket sequence
-+         * @param hashCode the hash code
-+         * @param key      the key
-+         * @param value    the value
-+         */
-+        protected LinkEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
-+            super(next, hashCode, key, value);
-+        }
-+    }
-+
-+    /**
-+     * Base Iterator that iterates in link order.
-+     */
-+    protected static abstract class LinkIterator <K,V> {
-+
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractLinkedMap<K, V> parent;
-+        /**
-+         * The current (last returned) entry
-+         */
-+        protected LinkEntry<K, V> last;
-+        /**
-+         * The next entry
-+         */
-+        protected LinkEntry<K, V> next;
-+        /**
-+         * The modification count expected
-+         */
-+        protected int expectedModCount;
-+
-+        protected LinkIterator(AbstractLinkedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+            this.next = parent.header.after;
-+            this.expectedModCount = parent.modCount;
-+        }
-+
-+        public boolean hasNext() {
-+            return (next != parent.header);
-+        }
-+
-+        public boolean hasPrevious() {
-+            return (next.before != parent.header);
-+        }
-+
-+        protected LinkEntry<K, V> nextEntry() {
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+            if (next == parent.header) {
-+                throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
-+            }
-+            last = next;
-+            next = next.after;
-+            return last;
-+        }
-+
-+        protected LinkEntry<K, V> previousEntry() {
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+            LinkEntry<K, V> previous = next.before;
-+            if (previous == parent.header) {
-+                throw new NoSuchElementException(AbstractHashedMap.NO_PREVIOUS_ENTRY);
-+            }
-+            next = previous;
-+            last = previous;
-+            return last;
-+        }
-+
-+        protected LinkEntry<K, V> currentEntry() {
-+            return last;
-+        }
-+
-+        public void remove() {
-+            if (last == null) {
-+                throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
-+            }
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+            parent.remove(last.getKey());
-+            last = null;
-+            expectedModCount = parent.modCount;
-+        }
-+
-+        public void reset() {
-+            last = null;
-+            next = parent.header.after;
-+        }
-+
-+        public String toString() {
-+            if (last != null) {
-+                return "Iterator[" + last.getKey() + "=" + last.getValue() + "]";
-+            } else {
-+                return "Iterator[]";
-+            }
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/AbstractMapDecorator.java
-@@ -0,0 +1,143 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.util.Collection;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Provides a base decorator that enables additional functionality to be added
-+ * to a Map via decoration.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated map.
-+ * <p/>
-+ * This implementation does not perform any special processing with
-+ * {@link #entrySet()}, {@link #keySet()} or {@link #values()}. Instead
-+ * it simply returns the set/collection from the wrapped map. This may be
-+ * undesirable, for example if you are trying to write a validating
-+ * implementation it would provide a loophole around the validation.
-+ * But, you might want that loophole, so this class is kept simple.
-+ *
-+ * @author Daniel Rall
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractMapDecorator <K,V> implements Map<K, V> {
-+
-+    /**
-+     * The map to decorate
-+     */
-+    protected transient Map<K, V> map;
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractMapDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractMapDecorator(Map<K, V> map) {
-+        if (map == null) {
-+            throw new IllegalArgumentException("Map must not be null");
-+        }
-+        this.map = map;
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected Map<K, V> getMap() {
-+        return map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void clear() {
-+        map.clear();
-+    }
-+
-+    public boolean containsKey(Object key) {
-+        return map.containsKey(key);
-+    }
-+
-+    public boolean containsValue(Object value) {
-+        return map.containsValue(value);
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        return map.entrySet();
-+    }
-+
-+    public V get(Object key) {
-+        return map.get(key);
-+    }
-+
-+    public boolean isEmpty() {
-+        return map.isEmpty();
-+    }
-+
-+    public Set<K> keySet() {
-+        return map.keySet();
-+    }
-+
-+    public V put(K key, V value) {
-+        return map.put(key, value);
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        map.putAll(mapToCopy);
-+    }
-+
-+    public V remove(Object key) {
-+        return map.remove(key);
-+    }
-+
-+    public int size() {
-+        return map.size();
-+    }
-+
-+    public Collection<V> values() {
-+        return map.values();
-+    }
-+
-+    public boolean equals(Object object) {
-+        if (object == this) {
-+            return true;
-+        }
-+        return map.equals(object);
-+    }
-+
-+    public int hashCode() {
-+        return map.hashCode();
-+    }
-+
-+    public String toString() {
-+        return map.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/AbstractOrderedMapDecorator.java
-@@ -0,0 +1,94 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.OrderedMap;
-+import org.apache.commons.collections15.OrderedMapIterator;
-+
-+/**
-+ * Provides a base decorator that enables additional functionality to be added
-+ * to an OrderedMap via decoration.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated map.
-+ * <p/>
-+ * This implementation does not perform any special processing with the map views.
-+ * Instead it simply returns the set/collection from the wrapped map. This may be
-+ * undesirable, for example if you are trying to write a validating implementation
-+ * it would provide a loophole around the validation.
-+ * But, you might want that loophole, so this class is kept simple.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractOrderedMapDecorator <K,V> extends AbstractMapDecorator<K, V> implements OrderedMap<K, V> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractOrderedMapDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractOrderedMapDecorator(OrderedMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected OrderedMap<K, V> getOrderedMap() {
-+        return (OrderedMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K firstKey() {
-+        return getOrderedMap().firstKey();
-+    }
-+
-+    public K lastKey() {
-+        return getOrderedMap().lastKey();
-+    }
-+
-+    public K nextKey(K key) {
-+        return getOrderedMap().nextKey(key);
-+    }
-+
-+    public K previousKey(K key) {
-+        return getOrderedMap().previousKey(key);
-+    }
-+
-+    public MapIterator<K, V> mapIterator() {
-+        return getOrderedMap().mapIterator();
-+    }
-+
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        return getOrderedMap().orderedMapIterator();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/AbstractReferenceMap.java
-@@ -0,0 +1,1028 @@
-+// Converted, with some major refactors required. Not as memory-efficient as before, could use additional refactoring.
-+// Perhaps use four different types of HashEntry classes for max efficiency:
-+//   normal HashEntry for HARD,HARD
-+//   HardRefEntry for HARD,(SOFT|WEAK)
-+//   RefHardEntry for (SOFT|WEAK),HARD
-+//   RefRefEntry for (SOFT|WEAK),(SOFT|WEAK)
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.keyvalue.DefaultMapEntry;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.lang.ref.Reference;
-+import java.lang.ref.ReferenceQueue;
-+import java.lang.ref.SoftReference;
-+import java.lang.ref.WeakReference;
-+import java.util.*;
-+
-+/**
-+ * An abstract implementation of a hash-based map that allows the entries to
-+ * be removed by the garbage collector.
-+ * <p/>
-+ * This class implements all the features necessary for a subclass reference
-+ * hash-based map. Key-value entries are stored in instances of the
-+ * <code>ReferenceEntry</code> class which can be overridden and replaced.
-+ * The iterators can similarly be replaced, without the need to replace the KeySet,
-+ * EntrySet and Values view classes.
-+ * <p/>
-+ * Overridable methods are provided to change the default hashing behaviour, and
-+ * to change how entries are added to and removed from the map. Hopefully, all you
-+ * need for unusual subclasses is here.
-+ * <p/>
-+ * When you construct an <code>AbstractReferenceMap</code>, you can specify what
-+ * kind of references are used to store the map's keys and values.
-+ * If non-hard references are used, then the garbage collector can remove
-+ * mappings if a key or value becomes unreachable, or if the JVM's memory is
-+ * running low. For information on how the different reference types behave,
-+ * see {@link Reference}.
-+ * <p/>
-+ * Different types of references can be specified for keys and values.
-+ * The keys can be configured to be weak but the values hard,
-+ * in which case this class will behave like a
-+ * <a href="http://java.sun.com/j2se/1.4/docs/api/java/util/WeakHashMap.html">
-+ * <code>WeakHashMap</code></a>. However, you can also specify hard keys and
-+ * weak values, or any other combination. The default constructor uses
-+ * hard keys and soft values, providing a memory-sensitive cache.
-+ * <p/>
-+ * This {@link Map} implementation does <i>not</i> allow null elements.
-+ * Attempting to add a null key or value to the map will raise a
-+ * <code>NullPointerException</code>.
-+ * <p/>
-+ * All the available iterators can be reset back to the start by casting to
-+ * <code>ResettableIterator</code> and calling <code>reset()</code>.
-+ * <p/>
-+ * This implementation is not synchronized.
-+ * You can use {@link java.util.Collections#synchronizedMap} to
-+ * provide synchronized access to a <code>ReferenceMap</code>.
-+ *
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @see java.lang.ref.Reference
-+ * @since Commons Collections 3.1 (extracted from ReferenceMap in 3.0)
-+ */
-+public abstract class AbstractReferenceMap <K,V> extends AbstractHashedMap<K, V> {
-+
-+    /**
-+     * Constant indicating that hard references should be used
-+     */
-+    public static final int HARD = 0;
-+
-+    /**
-+     * Constant indicating that soft references should be used
-+     */
-+    public static final int SOFT = 1;
-+
-+    /**
-+     * Constant indicating that weak references should be used
-+     */
-+    public static final int WEAK = 2;
-+
-+    /**
-+     * The reference type for keys.  Must be HARD, SOFT, WEAK.
-+     *
-+     * @serial
-+     */
-+    protected int keyType;
-+
-+    /**
-+     * The reference type for values.  Must be HARD, SOFT, WEAK.
-+     *
-+     * @serial
-+     */
-+    protected int valueType;
-+
-+    /**
-+     * Should the value be automatically purged when the associated key has been collected?
-+     */
-+    protected boolean purgeValues;
-+
-+    /**
-+     * ReferenceQueue used to eliminate stale mappings.
-+     * See purge.
-+     */
-+    private transient ReferenceQueue queue;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor used during deserialization.
-+     */
-+    protected AbstractReferenceMap() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructs a new empty map with the specified reference types,
-+     * load factor and initial capacity.
-+     *
-+     * @param keyType     the type of reference to use for keys;
-+     *                    must be {@link #SOFT} or {@link #WEAK}
-+     * @param valueType   the type of reference to use for values;
-+     *                    must be {@link #SOFT} or {@link #WEAK}
-+     * @param capacity    the initial capacity for the map
-+     * @param loadFactor  the load factor for the map
-+     * @param purgeValues should the value be automatically purged when the
-+     *                    key is garbage collected
-+     */
-+    protected AbstractReferenceMap(int keyType, int valueType, int capacity, float loadFactor, boolean purgeValues) {
-+        super(capacity, loadFactor);
-+        verify("keyType", keyType);
-+        verify("valueType", valueType);
-+        this.keyType = keyType;
-+        this.valueType = valueType;
-+        this.purgeValues = purgeValues;
-+    }
-+
-+    /**
-+     * Initialise this subclass during construction, cloning or deserialization.
-+     */
-+    protected void init() {
-+        queue = new ReferenceQueue();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks the type int is a valid value.
-+     *
-+     * @param name the name for error messages
-+     * @param type the type value to check
-+     * @throws IllegalArgumentException if the value if invalid
-+     */
-+    private static void verify(String name, int type) {
-+        if ((type < HARD) || (type > WEAK)) {
-+            throw new IllegalArgumentException(name + " must be HARD, SOFT, WEAK.");
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the size of the map.
-+     *
-+     * @return the size
-+     */
-+    public int size() {
-+        purgeBeforeRead();
-+        return super.size();
-+    }
-+
-+    /**
-+     * Checks whether the map is currently empty.
-+     *
-+     * @return true if the map is currently size zero
-+     */
-+    public boolean isEmpty() {
-+        purgeBeforeRead();
-+        return super.isEmpty();
-+    }
-+
-+    /**
-+     * Checks whether the map contains the specified key.
-+     *
-+     * @param key the key to search for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsKey(Object key) {
-+        purgeBeforeRead();
-+        Entry entry = getEntry(key);
-+        if (entry == null) {
-+            return false;
-+        }
-+        return (entry.getValue() != null);
-+    }
-+
-+    /**
-+     * Checks whether the map contains the specified value.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the value
-+     */
-+    public boolean containsValue(Object value) {
-+        purgeBeforeRead();
-+        if (value == null) {
-+            return false;
-+        }
-+        return super.containsValue(value);
-+    }
-+
-+    /**
-+     * Gets the value mapped to the key specified.
-+     *
-+     * @param key the key
-+     * @return the mapped value, null if no match
-+     */
-+    public V get(Object key) {
-+        purgeBeforeRead();
-+        Entry<K, V> entry = getEntry(key);
-+        if (entry == null) {
-+            return null;
-+        }
-+        return entry.getValue();
-+    }
-+
-+
-+    /**
-+     * Puts a key-value mapping into this map.
-+     * Neither the key nor the value may be null.
-+     *
-+     * @param key   the key to add, must not be null
-+     * @param value the value to add, must not be null
-+     * @return the value previously mapped to this key, null if none
-+     * @throws NullPointerException if either the key or value is null
-+     */
-+    public V put(K key, V value) {
-+        if (key == null) {
-+            throw new NullPointerException("null keys not allowed");
-+        }
-+        if (value == null) {
-+            throw new NullPointerException("null values not allowed");
-+        }
-+
-+        purgeBeforeWrite();
-+        return super.put(key, value);
-+    }
-+
-+    /**
-+     * Removes the specified mapping from this map.
-+     *
-+     * @param key the mapping to remove
-+     * @return the value mapped to the removed key, null if key not in map
-+     */
-+    public V remove(Object key) {
-+        if (key == null) {
-+            return null;
-+        }
-+        purgeBeforeWrite();
-+        return super.remove(key);
-+    }
-+
-+    /**
-+     * Clears this map.
-+     */
-+    public void clear() {
-+        super.clear();
-+        while (queue.poll() != null) {
-+        } // drain the queue
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets a MapIterator over the reference map.
-+     * The iterator only returns valid key/value pairs.
-+     *
-+     * @return a map iterator
-+     */
-+    public MapIterator<K, V> mapIterator() {
-+        return new ReferenceMapIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Returns a set view of this map's entries.
-+     * An iterator returned entry is valid until <code>next()</code> is called again.
-+     * The <code>setValue()</code> method on the <code>toArray</code> entries has no effect.
-+     *
-+     * @return a set view of this map's entries
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        if (entrySet == null) {
-+            entrySet = new ReferenceEntrySet<K, V>(this);
-+        }
-+        return entrySet;
-+    }
-+
-+    /**
-+     * Returns a set view of this map's keys.
-+     *
-+     * @return a set view of this map's keys
-+     */
-+    public Set<K> keySet() {
-+        if (keySet == null) {
-+            keySet = new ReferenceKeySet<K, V>(this);
-+        }
-+        return keySet;
-+    }
-+
-+    /**
-+     * Returns a collection view of this map's values.
-+     *
-+     * @return a set view of this map's values
-+     */
-+    public Collection<V> values() {
-+        if (values == null) {
-+            values = new ReferenceValues<K, V>(this);
-+        }
-+        return values;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Purges stale mappings from this map before read operations.
-+     * <p/>
-+     * This implementation calls {@link #purge()} to maintain a consistent state.
-+     */
-+    protected void purgeBeforeRead() {
-+        purge();
-+    }
-+
-+    /**
-+     * Purges stale mappings from this map before write operations.
-+     * <p/>
-+     * This implementation calls {@link #purge()} to maintain a consistent state.
-+     */
-+    protected void purgeBeforeWrite() {
-+        purge();
-+    }
-+
-+    /**
-+     * Purges stale mappings from this map.
-+     * <p/>
-+     * Note that this method is not synchronized!  Special
-+     * care must be taken if, for instance, you want stale
-+     * mappings to be removed on a periodic basis by some
-+     * background thread.
-+     */
-+    protected void purge() {
-+        Reference ref = queue.poll();
-+        while (ref != null) {
-+            purge(ref);
-+            ref = queue.poll();
-+        }
-+    }
-+
-+    /**
-+     * Purges the specified reference.
-+     *
-+     * @param ref the reference to purge
-+     */
-+    protected void purge(Reference ref) {
-+        // The hashCode of the reference is the hashCode of the
-+        // mapping key, even if the reference refers to the 
-+        // mapping value...
-+        int hash = ref.hashCode();
-+        int index = hashIndex(hash, data.length);
-+        HashEntry<K, V> previous = null;
-+        HashEntry<K, V> entry = data[index];
-+        while (entry != null) {
-+            if (((ReferenceEntry<K, V>) entry).purge(ref)) {
-+                if (previous == null) {
-+                    data[index] = entry.next;
-+                } else {
-+                    previous.next = entry.next;
-+                }
-+                this.size--;
-+                return;
-+            }
-+            previous = entry;
-+            entry = entry.next;
-+        }
-+
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the entry mapped to the key specified.
-+     *
-+     * @param key the key
-+     * @return the entry, null if no match
-+     */
-+    protected HashEntry<K, V> getEntry(Object key) {
-+        if (key == null) {
-+            return null;
-+        } else {
-+            return super.getEntry(key);
-+        }
-+    }
-+
-+    /**
-+     * Gets the hash code for a MapEntry.
-+     * Subclasses can override this, for example to use the identityHashCode.
-+     *
-+     * @param key   the key to get a hash code for, may be null
-+     * @param value the value to get a hash code for, may be null
-+     * @return the hash code, as per the MapEntry specification
-+     */
-+    protected int hashEntry(Object key, Object value) {
-+        return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
-+    }
-+
-+    /**
-+     * Compares two keys, in internal converted form, to see if they are equal.
-+     * <p/>
-+     * This implementation converts the key from the entry to a real reference
-+     * before comparison.
-+     *
-+     * @param key1 the first key to compare passed in from outside
-+     * @param key2 the second key extracted from the entry via <code>entry.key</code>
-+     * @return true if equal
-+     */
-+    protected boolean isEqualKey(Object key1, Object key2) {
-+        //if ((key1 == null) && (key2 != null) || (key1 != null) || (key2 == null)) {
-+        //    return false;
-+        //}
-+        // GenericsNote: Conversion from reference handled by getKey() which replaced all .key references
-+        //key2 = (keyType > HARD ? ((Reference) key2).get() : key2);
-+        return (key1 == key2 || key1.equals(key2));
-+    }
-+
-+    /**
-+     * Creates a ReferenceEntry instead of a HashEntry.
-+     *
-+     * @param next     the next entry in sequence
-+     * @param hashCode the hash code to use
-+     * @param key      the key to store
-+     * @param value    the value to store
-+     * @return the newly created entry
-+     */
-+    public HashEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
-+        return new ReferenceEntry<K, V>(this, (ReferenceEntry<K, V>) next, hashCode, key, value);
-+    }
-+
-+    /**
-+     * Creates an entry set iterator.
-+     *
-+     * @return the entrySet iterator
-+     */
-+    protected Iterator<Map.Entry<K, V>> createEntrySetIterator() {
-+        return new ReferenceEntrySetIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Creates an key set iterator.
-+     *
-+     * @return the keySet iterator
-+     */
-+    protected Iterator<K> createKeySetIterator() {
-+        return new ReferenceKeySetIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Creates an values iterator.
-+     *
-+     * @return the values iterator
-+     */
-+    protected Iterator<V> createValuesIterator() {
-+        return new ReferenceValuesIterator<K, V>(this);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * EntrySet implementation.
-+     */
-+    static class ReferenceEntrySet <K,V> extends EntrySet<K, V> {
-+
-+        protected ReferenceEntrySet(AbstractHashedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public Object[] toArray() {
-+            return toArray(new Object[0]);
-+        }
-+
-+        public <T> T[] toArray(T[] arr) {
-+            // special implementation to handle disappearing entries
-+            ArrayList<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>();
-+            Iterator<Map.Entry<K, V>> iterator = iterator();
-+            while (iterator.hasNext()) {
-+                Map.Entry<K, V> e = iterator.next();
-+                list.add(new DefaultMapEntry<K, V>(e.getKey(), e.getValue()));
-+            }
-+            return list.toArray(arr);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * KeySet implementation.
-+     */
-+    static class ReferenceKeySet <K,V> extends KeySet<K, V> {
-+
-+        protected ReferenceKeySet(AbstractHashedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public Object[] toArray() {
-+            return toArray(new Object[0]);
-+        }
-+
-+        public <T> T[] toArray(T[] arr) {
-+            // special implementation to handle disappearing keys
-+            List<K> list = new ArrayList<K>(parent.size());
-+            for (Iterator<K> it = iterator(); it.hasNext();) {
-+                list.add(it.next());
-+            }
-+            return list.toArray(arr);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Values implementation.
-+     */
-+    static class ReferenceValues <K,V> extends Values<K, V> {
-+
-+        protected ReferenceValues(AbstractHashedMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public Object[] toArray() {
-+            return toArray(new Object[0]);
-+        }
-+
-+        public <T> T[] toArray(T[] arr) {
-+            // special implementation to handle disappearing values
-+            List<V> list = new ArrayList<V>(parent.size());
-+            for (Iterator<V> it = iterator(); it.hasNext();) {
-+                list.add(it.next());
-+            }
-+            return list.toArray(arr);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * A MapEntry implementation for the map.
-+     * <p/>
-+     * If getKey() or getValue() returns null, it means
-+     * the mapping is stale and should be removed.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected static class ReferenceEntry <K,V> extends HashEntry<K, V> {
-+        /**
-+         * The parent map
-+         */
-+        protected final AbstractReferenceMap<K, V> parent;
-+
-+        protected Reference<K> refKey;
-+        protected Reference<V> refValue;
-+
-+        /**
-+         * Creates a new entry object for the ReferenceMap.
-+         *
-+         * @param parent   the parent map
-+         * @param next     the next entry in the hash bucket
-+         * @param hashCode the hash code of the key
-+         * @param key      the key
-+         * @param value    the value
-+         */
-+        public ReferenceEntry(AbstractReferenceMap<K, V> parent, ReferenceEntry<K, V> next, int hashCode, K key, V value) {
-+            super(next, hashCode, null, null);
-+            this.parent = parent;
-+            if (parent.keyType != HARD) {
-+                refKey = toReference(parent.keyType, key, hashCode);
-+            } else {
-+                this.setKey(key);
-+            }
-+            if (parent.valueType != HARD) {
-+                refValue = toReference(parent.valueType, value, hashCode); // the key hashCode is passed in deliberately
-+            } else {
-+                this.setValue(value);
-+            }
-+        }
-+
-+        /**
-+         * Gets the key from the entry.
-+         * This method dereferences weak and soft keys and thus may return null.
-+         *
-+         * @return the key, which may be null if it was garbage collected
-+         */
-+        public K getKey() {
-+            return (parent.keyType > HARD) ? refKey.get() : super.getKey();
-+        }
-+
-+        /**
-+         * Gets the value from the entry.
-+         * This method dereferences weak and soft value and thus may return null.
-+         *
-+         * @return the value, which may be null if it was garbage collected
-+         */
-+        public V getValue() {
-+            return (parent.valueType > HARD) ? refValue.get() : super.getValue();
-+        }
-+
-+        /**
-+         * Sets the value of the entry.
-+         *
-+         * @param obj the object to store
-+         * @return the previous value
-+         */
-+        public V setValue(V obj) {
-+            V old = getValue();
-+            if (parent.valueType > HARD) {
-+                refValue.clear();
-+                refValue = toReference(parent.valueType, obj, hashCode);
-+            } else {
-+                super.setValue(obj);
-+            }
-+            return old;
-+        }
-+
-+        /**
-+         * Compares this map entry to another.
-+         * <p/>
-+         * This implementation uses <code>isEqualKey</code> and
-+         * <code>isEqualValue</code> on the main map for comparison.
-+         *
-+         * @param obj the other map entry to compare to
-+         * @return true if equal, false if not
-+         */
-+        public boolean equals(Object obj) {
-+            if (obj == this) {
-+                return true;
-+            }
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+
-+            Map.Entry entry = (Map.Entry) obj;
-+            Object entryKey = entry.getKey();  // convert to hard reference
-+            Object entryValue = entry.getValue();  // convert to hard reference
-+            if ((entryKey == null) || (entryValue == null)) {
-+                return false;
-+            }
-+            // compare using map methods, aiding identity subclass
-+            // note that key is direct access and value is via method
-+            return parent.isEqualKey(entryKey, getKey()) && parent.isEqualValue(entryValue, getValue());
-+        }
-+
-+        /**
-+         * Gets the hashcode of the entry using temporary hard references.
-+         * <p/>
-+         * This implementation uses <code>hashEntry</code> on the main map.
-+         *
-+         * @return the hashcode of the entry
-+         */
-+        public int hashCode() {
-+            return parent.hashEntry(getKey(), getValue());
-+        }
-+
-+        /**
-+         * Constructs a reference of the given type to the given referent.
-+         * The reference is registered with the queue for later purging.
-+         *
-+         * @param type     HARD, SOFT or WEAK
-+         * @param referent the object to refer to
-+         * @param hash     the hash code of the <i>key</i> of the mapping;
-+         *                 this number might be different from referent.hashCode() if
-+         *                 the referent represents a value and not a key
-+         */
-+        protected <T> Reference<T> toReference(int type, T referent, int hash) {
-+            switch (type) {
-+                case SOFT:
-+                    return new SoftRef<T>(hash, referent, parent.queue);
-+                case WEAK:
-+                    return new WeakRef<T>(hash, referent, parent.queue);
-+                default:
-+                    throw new Error("Attempt to create hard reference in ReferenceMap!");
-+            }
-+        }
-+
-+        /**
-+         * Purges the specified reference
-+         *
-+         * @param ref the reference to purge
-+         * @return true or false
-+         */
-+        boolean purge(Reference ref) {
-+            boolean r = (parent.keyType > HARD) && (refKey == ref);
-+            r = r || ((parent.valueType > HARD) && (refValue == ref));
-+            if (r) {
-+                if (parent.keyType > HARD) {
-+                    refKey.clear();
-+                }
-+                if (parent.valueType > HARD) {
-+                    refValue.clear();
-+                } else if (parent.purgeValues) {
-+                    setValue(null);
-+                }
-+            }
-+            return r;
-+        }
-+
-+        /**
-+         * Gets the next entry in the bucket.
-+         *
-+         * @return the next entry in the bucket
-+         */
-+        protected ReferenceEntry<K, V> next() {
-+            return (ReferenceEntry<K, V>) next;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * The EntrySet iterator.
-+     */
-+    static class ReferenceIteratorBase <K,V> {
-+        /**
-+         * The parent map
-+         */
-+        final AbstractReferenceMap<K, V> parent;
-+
-+        // These fields keep track of where we are in the table.
-+        int index;
-+        ReferenceEntry<K, V> entry;
-+        ReferenceEntry<K, V> previous;
-+
-+        // These Object fields provide hard references to the
-+        // current and next entry; this assures that if hasNext()
-+        // returns true, next() will actually return a valid element.
-+        K nextKey;
-+        V nextValue;
-+        K currentKey;
-+        V currentValue;
-+
-+        int expectedModCount;
-+
-+        public ReferenceIteratorBase(AbstractReferenceMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+            index = (parent.size() != 0 ? parent.data.length : 0);
-+            // have to do this here!  size() invocation above
-+            // may have altered the modCount.
-+            expectedModCount = parent.modCount;
-+        }
-+
-+        public boolean hasNext() {
-+            checkMod();
-+            while (nextNull()) {
-+                ReferenceEntry<K, V> e = entry;
-+                int i = index;
-+                while ((e == null) && (i > 0)) {
-+                    i--;
-+                    e = (ReferenceEntry<K, V>) parent.data[i];
-+                }
-+                entry = e;
-+                index = i;
-+                if (e == null) {
-+                    currentKey = null;
-+                    currentValue = null;
-+                    return false;
-+                }
-+                nextKey = e.getKey();
-+                nextValue = e.getValue();
-+                if (nextNull()) {
-+                    entry = entry.next();
-+                }
-+            }
-+            return true;
-+        }
-+
-+        private void checkMod() {
-+            if (parent.modCount != expectedModCount) {
-+                throw new ConcurrentModificationException();
-+            }
-+        }
-+
-+        private boolean nextNull() {
-+            return (nextKey == null) || (nextValue == null);
-+        }
-+
-+        protected ReferenceEntry<K, V> nextEntry() {
-+            checkMod();
-+            if (nextNull() && !hasNext()) {
-+                throw new NoSuchElementException();
-+            }
-+            previous = entry;
-+            entry = entry.next();
-+            currentKey = nextKey;
-+            currentValue = nextValue;
-+            nextKey = null;
-+            nextValue = null;
-+            return previous;
-+        }
-+
-+        protected ReferenceEntry<K, V> currentEntry() {
-+            checkMod();
-+            return previous;
-+        }
-+
-+        public ReferenceEntry<K, V> superNext() {
-+            return nextEntry();
-+        }
-+
-+        public void remove() {
-+            checkMod();
-+            if (previous == null) {
-+                throw new IllegalStateException();
-+            }
-+            parent.remove(currentKey);
-+            previous = null;
-+            currentKey = null;
-+            currentValue = null;
-+            expectedModCount = parent.modCount;
-+        }
-+    }
-+
-+    /**
-+     * The EntrySet iterator.
-+     */
-+    static class ReferenceEntrySetIterator <K,V> extends ReferenceIteratorBase<K, V> implements Iterator<Map.Entry<K, V>> {
-+
-+        public ReferenceEntrySetIterator(AbstractReferenceMap<K, V> abstractReferenceMap) {
-+            super(abstractReferenceMap);
-+        }
-+
-+        public ReferenceEntry<K, V> next() {
-+            return superNext();
-+        }
-+
-+    }
-+
-+    /**
-+     * The keySet iterator.
-+     */
-+    static class ReferenceKeySetIterator <K,V> extends ReferenceIteratorBase<K, V> implements Iterator<K> {
-+
-+        ReferenceKeySetIterator(AbstractReferenceMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public K next() {
-+            return nextEntry().getKey();
-+        }
-+    }
-+
-+    /**
-+     * The values iterator.
-+     */
-+    static class ReferenceValuesIterator <K,V> extends ReferenceIteratorBase<K, V> implements Iterator<V> {
-+
-+        ReferenceValuesIterator(AbstractReferenceMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public V next() {
-+            return nextEntry().getValue();
-+        }
-+    }
-+
-+    /**
-+     * The MapIterator implementation.
-+     */
-+    static class ReferenceMapIterator <K,V> extends ReferenceIteratorBase<K, V> implements MapIterator<K, V> {
-+
-+        protected ReferenceMapIterator(AbstractReferenceMap<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public K next() {
-+            return nextEntry().getKey();
-+        }
-+
-+        public K getKey() {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
-+            }
-+            return current.getKey();
-+        }
-+
-+        public V getValue() {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
-+            }
-+            return current.getValue();
-+        }
-+
-+        public V setValue(V value) {
-+            HashEntry<K, V> current = currentEntry();
-+            if (current == null) {
-+                throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
-+            }
-+            return current.setValue(value);
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    // These two classes store the hashCode of the key of
-+    // of the mapping, so that after they're dequeued a quick
-+    // lookup of the bucket in the table can occur.
-+
-+    /**
-+     * A soft reference holder.
-+     */
-+    static class SoftRef <T> extends SoftReference<T> {
-+        /**
-+         * the hashCode of the key (even if the reference points to a value)
-+         */
-+        private int hash;
-+
-+        public SoftRef(int hash, T r, ReferenceQueue q) {
-+            super(r, q);
-+            this.hash = hash;
-+        }
-+
-+        public int hashCode() {
-+            return hash;
-+        }
-+    }
-+
-+    /**
-+     * A weak reference holder.
-+     */
-+    static class WeakRef <T> extends WeakReference<T> {
-+        /**
-+         * the hashCode of the key (even if the reference points to a value)
-+         */
-+        private int hash;
-+
-+        public WeakRef(int hash, T r, ReferenceQueue q) {
-+            super(r, q);
-+            this.hash = hash;
-+        }
-+
-+        public int hashCode() {
-+            return hash;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Replaces the superclass method to store the state of this class.
-+     * <p/>
-+     * Serialization is not one of the JDK's nicest topics. Normal serialization will
-+     * initialise the superclass before the subclass. Sometimes however, this isn't
-+     * what you want, as in this case the <code>put()</code> method on read can be
-+     * affected by subclass state.
-+     * <p/>
-+     * The solution adopted here is to serialize the state data of this class in
-+     * this protected method. This method must be called by the
-+     * <code>writeObject()</code> of the first serializable subclass.
-+     * <p/>
-+     * Subclasses may override if they have a specific field that must be present
-+     * on read before this implementation will work. Generally, the read determines
-+     * what must be serialized here, if anything.
-+     *
-+     * @param out the output stream
-+     */
-+    protected void doWriteObject(ObjectOutputStream out) throws IOException {
-+        out.writeInt(keyType);
-+        out.writeInt(valueType);
-+        out.writeBoolean(purgeValues);
-+        out.writeFloat(loadFactor);
-+        out.writeInt(data.length);
-+        for (MapIterator it = mapIterator(); it.hasNext();) {
-+            out.writeObject(it.next());
-+            out.writeObject(it.getValue());
-+        }
-+        out.writeObject(null);  // null terminate map
-+        // do not call super.doWriteObject() as code there doesn't work for reference map
-+    }
-+
-+    /**
-+     * Replaces the superclassm method to read the state of this class.
-+     * <p/>
-+     * Serialization is not one of the JDK's nicest topics. Normal serialization will
-+     * initialise the superclass before the subclass. Sometimes however, this isn't
-+     * what you want, as in this case the <code>put()</code> method on read can be
-+     * affected by subclass state.
-+     * <p/>
-+     * The solution adopted here is to deserialize the state data of this class in
-+     * this protected method. This method must be called by the
-+     * <code>readObject()</code> of the first serializable subclass.
-+     * <p/>
-+     * Subclasses may override if the subclass has a specific field that must be present
-+     * before <code>put()</code> or <code>calculateThreshold()</code> will work correctly.
-+     *
-+     * @param in the input stream
-+     */
-+    protected void doReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        this.keyType = in.readInt();
-+        this.valueType = in.readInt();
-+        this.purgeValues = in.readBoolean();
-+        this.loadFactor = in.readFloat();
-+        int capacity = in.readInt();
-+        init();
-+        data = new HashEntry[capacity];
-+        while (true) {
-+            K key = (K) in.readObject();
-+            if (key == null) {
-+                break;
-+            }
-+            V value = (V) in.readObject();
-+            put(key, value);
-+        }
-+        threshold = calculateThreshold(data.length, loadFactor);
-+        // do not call super.doReadObject() as code there doesn't work for reference map
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/AbstractSortedMapDecorator.java
-@@ -0,0 +1,93 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.util.Comparator;
-+import java.util.SortedMap;
-+
-+/**
-+ * Provides a base decorator that enables additional functionality to be added
-+ * to a Map via decoration.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated map.
-+ * <p/>
-+ * This implementation does not perform any special processing with the map views.
-+ * Instead it simply returns the set/collection from the wrapped map. This may be
-+ * undesirable, for example if you are trying to write a validating implementation
-+ * it would provide a loophole around the validation.
-+ * But, you might want that loophole, so this class is kept simple.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractSortedMapDecorator <K,V> extends AbstractMapDecorator<K, V> implements SortedMap<K, V> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractSortedMapDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if the collection is null
-+     */
-+    public AbstractSortedMapDecorator(SortedMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected SortedMap<K, V> getSortedMap() {
-+        return (SortedMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Comparator<? super K> comparator() {
-+        return getSortedMap().comparator();
-+    }
-+
-+    public K firstKey() {
-+        return getSortedMap().firstKey();
-+    }
-+
-+    public SortedMap<K, V> headMap(K toKey) {
-+        return getSortedMap().headMap(toKey);
-+    }
-+
-+    public K lastKey() {
-+        return getSortedMap().lastKey();
-+    }
-+
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        return getSortedMap().subMap(fromKey, toKey);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        return getSortedMap().tailMap(fromKey);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/CaseInsensitiveMap.java
-@@ -0,0 +1,168 @@
-+// GenericsNote: Converted -- refactored heavily, and now must be a map of String -> ?.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * A case-insensitive <code>Map</code>.
-+ * <p/>
-+ * As entries are added to the map, keys are converted to all lowercase. A new
-+ * key is compared to existing keys by comparing <code>newKey.toLower()</code>
-+ * to the lowercase values in the current <code>KeySet.</code>
-+ * <p/>
-+ * Null keys are supported.
-+ * <p/>
-+ * The <code>keySet()</code> method returns all lowercase keys, or nulls.
-+ * <p/>
-+ * Example:
-+ * <pre><code>
-+ *  Map map = new CaseInsensitiveMap();
-+ *  map.put("One", "One");
-+ *  map.put("Two", "Two");
-+ *  map.put(null, "Three");
-+ *  map.put("one", "Four");
-+ * </code></pre>
-+ * creates a <code>CaseInsensitiveMap</code> with three entries.<br>
-+ * <code>map.get(null)</code> returns <code>"Three"</code> and <code>map.get("ONE")</code>
-+ * returns <code>"Four".</code>  The <code>Set</code> returned by <code>keySet()</code>
-+ * equals <code>{"one", "two", null}.</code>
-+ *
-+ * @author Matt Hall, John Watkinson, Commons-Collections team
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class CaseInsensitiveMap <V> extends AbstractHashedMap<String, V> implements Serializable, Cloneable {
-+
-+    /**
-+     * Serialisation version
-+     */
-+    private static final long serialVersionUID = -7074655917369299456L;
-+
-+    /**
-+     * Constructs a new empty map with default size and load factor.
-+     */
-+    public CaseInsensitiveMap() {
-+        super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_THRESHOLD);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     */
-+    public CaseInsensitiveMap(int initialCapacity) {
-+        super(initialCapacity);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @param loadFactor      the load factor
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     * @throws IllegalArgumentException if the load factor is less than zero
-+     */
-+    public CaseInsensitiveMap(int initialCapacity, float loadFactor) {
-+        super(initialCapacity, loadFactor);
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     * <p/>
-+     * Keys will be converted to lower case strings, which may cause
-+     * some entries to be removed (if string representation of keys differ
-+     * only by character case).
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException if the map is null
-+     */
-+    public CaseInsensitiveMap(Map<? extends String, ? extends V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Converts keys to lower case.
-+     * <p/>
-+     * Returns null if key is null.
-+     *
-+     * @param key the key convert
-+     * @return the converted key
-+     */
-+    protected String convertKey(String key) {
-+        if (key != null) {
-+            return key.toString().toLowerCase();
-+        } else {
-+            return null;
-+        }
-+    }
-+
-+    @Override public V get(Object key) {
-+        if (!(key instanceof String)) {
-+            return super.get(key);
-+        }
-+        return super.get(convertKey((String) key));
-+    }
-+
-+    @Override public V put(String s, V v) {
-+        return super.put(convertKey(s), v);
-+    }
-+
-+    @Override public void putAll(Map<? extends String, ? extends V> map) {
-+        Set entries = map.entrySet();
-+        for (Iterator<Entry<? extends String, ? extends V>> iterator = entries.iterator(); iterator.hasNext();) {
-+            Entry<? extends String, ? extends V> entry = iterator.next();
-+            put(entry.getKey(), entry.getValue());
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     *
-+     * @return a shallow clone
-+     */
-+    public Object clone() {
-+        return super.clone();
-+    }
-+
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/CompositeMap.java
-@@ -0,0 +1,523 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.CollectionUtils;
-+import org.apache.commons.collections15.collection.CompositeCollection;
-+import org.apache.commons.collections15.set.CompositeSet;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Decorates a map of other maps to provide a single unified view.
-+ * <p/>
-+ * Changes made to this map will actually be made on the decorated map.
-+ * Add and remove operations require the use of a pluggable strategy. If no
-+ * strategy is provided then add and remove are unsupported.
-+ *
-+ * @author Matt Hall, John Watkinson, Brian McCallister
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class CompositeMap <K,V> implements Map<K, V> {
-+
-+    /**
-+     * Array of all maps in the composite
-+     */
-+    private Map[] composite;
-+
-+    /**
-+     * Handle mutation operations
-+     */
-+    private MapMutator<K, V> mutator;
-+
-+    /**
-+     * Create a new, empty, CompositeMap.
-+     */
-+    public CompositeMap() {
-+        this(new Map[]{}, null);
-+    }
-+
-+    /**
-+     * Create a new CompositeMap with two composited Map instances.
-+     *
-+     * @param one the first Map to be composited
-+     * @param two the second Map to be composited
-+     * @throws IllegalArgumentException if there is a key collision
-+     */
-+    public CompositeMap(Map<? extends K, ? extends V> one, Map<? extends K, ? extends V> two) {
-+        this(new Map[]{one, two}, null);
-+    }
-+
-+    /**
-+     * Create a new CompositeMap with two composited Map instances.
-+     *
-+     * @param one     the first Map to be composited
-+     * @param two     the second Map to be composited
-+     * @param mutator MapMutator to be used for mutation operations
-+     */
-+    public CompositeMap(Map<? extends K, ? extends V> one, Map<? extends K, ? extends V> two, MapMutator<K, V> mutator) {
-+        this(new Map[]{one, two}, mutator);
-+    }
-+
-+    /**
-+     * Create a new CompositeMap which composites all of the Map instances in the
-+     * argument. It copies the argument array, it does not use it directly.
-+     *
-+     * @param composite the Maps to be composited
-+     * @throws IllegalArgumentException if there is a key collision
-+     */
-+    public CompositeMap(Map[] composite) {
-+        this(composite, null);
-+    }
-+
-+    /**
-+     * Create a new CompositeMap which composites all of the Map instances in the
-+     * argument. It copies the argument array, it does not use it directly.
-+     *
-+     * @param composite Maps to be composited
-+     * @param mutator   MapMutator to be used for mutation operations
-+     */
-+    public CompositeMap(Map[] composite, MapMutator<K, V> mutator) {
-+        this.mutator = mutator;
-+        this.composite = new Map[0];
-+        for (int i = composite.length - 1; i >= 0; --i) {
-+            this.addComposited(composite[i]);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Specify the MapMutator to be used by mutation operations.
-+     *
-+     * @param mutator the MapMutator to be used for mutation delegation
-+     */
-+    public void setMutator(MapMutator<K, V> mutator) {
-+        this.mutator = mutator;
-+    }
-+
-+    /**
-+     * Add an additional Map to the composite.
-+     *
-+     * @param map the Map to be added to the composite
-+     * @throws IllegalArgumentException if there is a key collision and there is no
-+     *                                  MapMutator set to handle it.
-+     */
-+    public synchronized void addComposited(Map<? extends K, ? extends V> map) throws IllegalArgumentException {
-+        for (int i = composite.length - 1; i >= 0; --i) {
-+            Collection<K> intersect = (Collection<K>) CollectionUtils.intersection(this.composite[i].keySet(), map.keySet());
-+            if (intersect.size() != 0) {
-+                if (this.mutator == null) {
-+                    throw new IllegalArgumentException("Key collision adding Map to CompositeMap");
-+                } else {
-+                    this.mutator.resolveCollision(this, this.composite[i], map, intersect);
-+                }
-+            }
-+        }
-+        Map[] temp = new Map[this.composite.length + 1];
-+        System.arraycopy(this.composite, 0, temp, 0, this.composite.length);
-+        temp[temp.length - 1] = map;
-+        this.composite = temp;
-+    }
-+
-+    /**
-+     * Remove a Map from the composite.
-+     *
-+     * @param map the Map to be removed from the composite
-+     * @return The removed Map or <code>null</code> if map is not in the composite
-+     */
-+    public synchronized Map<? extends K, ? extends V> removeComposited(Map<? extends K, ? extends V> map) {
-+        int size = this.composite.length;
-+        for (int i = 0; i < size; ++i) {
-+            if (this.composite[i].equals(map)) {
-+                Map[] temp = new Map[size - 1];
-+                System.arraycopy(this.composite, 0, temp, 0, i);
-+                System.arraycopy(this.composite, i + 1, temp, i, size - i - 1);
-+                this.composite = temp;
-+                return map;
-+            }
-+        }
-+        return null;
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Calls <code>clear()</code> on all composited Maps.
-+     *
-+     * @throws UnsupportedOperationException if any of the composited Maps do not support clear()
-+     */
-+    public void clear() {
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            this.composite[i].clear();
-+        }
-+    }
-+
-+    /**
-+     * Returns <tt>true</tt> if this map contains a mapping for the specified
-+     * key.  More formally, returns <tt>true</tt> if and only if
-+     * this map contains at a mapping for a key <tt>k</tt> such that
-+     * <tt>(key==null ? k==null : key.equals(k))</tt>.  (There can be
-+     * at most one such mapping.)
-+     *
-+     * @param key key whose presence in this map is to be tested.
-+     * @return <tt>true</tt> if this map contains a mapping for the specified
-+     *         key.
-+     * @throws ClassCastException   if the key is of an inappropriate type for
-+     *                              this map (optional).
-+     * @throws NullPointerException if the key is <tt>null</tt> and this map
-+     *                              does not not permit <tt>null</tt> keys (optional).
-+     */
-+    public boolean containsKey(Object key) {
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            if (this.composite[i].containsKey(key)) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Returns <tt>true</tt> if this map maps one or more keys to the
-+     * specified value.  More formally, returns <tt>true</tt> if and only if
-+     * this map contains at least one mapping to a value <tt>v</tt> such that
-+     * <tt>(value==null ? v==null : value.equals(v))</tt>.  This operation
-+     * will probably require time linear in the map size for most
-+     * implementations of the <tt>Map</tt> interface.
-+     *
-+     * @param value value whose presence in this map is to be tested.
-+     * @return <tt>true</tt> if this map maps one or more keys to the
-+     *         specified value.
-+     * @throws ClassCastException   if the value is of an inappropriate type for
-+     *                              this map (optional).
-+     * @throws NullPointerException if the value is <tt>null</tt> and this map
-+     *                              does not not permit <tt>null</tt> values (optional).
-+     */
-+    public boolean containsValue(Object value) {
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            if (this.composite[i].containsValue(value)) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Returns a set view of the mappings contained in this map.  Each element
-+     * in the returned set is a <code>Map.Entry</code>.  The set is backed by the
-+     * map, so changes to the map are reflected in the set, and vice-versa.
-+     * If the map is modified while an iteration over the set is in progress,
-+     * the results of the iteration are undefined.  The set supports element
-+     * removal, which removes the corresponding mapping from the map, via the
-+     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
-+     * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not support
-+     * the <tt>add</tt> or <tt>addAll</tt> operations.
-+     * <p/>
-+     * This implementation returns a <code>CompositeSet</code> which
-+     * composites the entry sets from all of the composited maps.
-+     *
-+     * @return a set view of the mappings contained in this map.
-+     * @see CompositeSet
-+     */
-+    public Set entrySet() {
-+        CompositeSet<Map.Entry<K, V>> entries = new CompositeSet<Map.Entry<K, V>>();
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            entries.addComposited(this.composite[i].entrySet());
-+        }
-+        return entries;
-+    }
-+
-+    /**
-+     * Returns the value to which this map maps the specified key.  Returns
-+     * <tt>null</tt> if the map contains no mapping for this key.  A return
-+     * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
-+     * map contains no mapping for the key; it's also possible that the map
-+     * explicitly maps the key to <tt>null</tt>.  The <tt>containsKey</tt>
-+     * operation may be used to distinguish these two cases.
-+     * <p/>
-+     * <p>More formally, if this map contains a mapping from a key
-+     * <tt>k</tt> to a value <tt>v</tt> such that <tt>(key==null ? k==null :
-+     * key.equals(k))</tt>, then this method returns <tt>v</tt>; otherwise
-+     * it returns <tt>null</tt>.  (There can be at most one such mapping.)
-+     *
-+     * @param key key whose associated value is to be returned.
-+     * @return the value to which this map maps the specified key, or
-+     *         <tt>null</tt> if the map contains no mapping for this key.
-+     * @throws ClassCastException   if the key is of an inappropriate type for
-+     *                              this map (optional).
-+     * @throws NullPointerException key is <tt>null</tt> and this map does not
-+     *                              not permit <tt>null</tt> keys (optional).
-+     * @see #containsKey(Object)
-+     */
-+    public V get(Object key) {
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            if (this.composite[i].containsKey(key)) {
-+                return (V) this.composite[i].get(key);
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Returns <tt>true</tt> if this map contains no key-value mappings.
-+     *
-+     * @return <tt>true</tt> if this map contains no key-value mappings.
-+     */
-+    public boolean isEmpty() {
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            if (!this.composite[i].isEmpty()) {
-+                return false;
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Returns a set view of the keys contained in this map.  The set is
-+     * backed by the map, so changes to the map are reflected in the set, and
-+     * vice-versa.  If the map is modified while an iteration over the set is
-+     * in progress, the results of the iteration are undefined.  The set
-+     * supports element removal, which removes the corresponding mapping from
-+     * the map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
-+     * <tt>removeAll</tt> <tt>retainAll</tt>, and <tt>clear</tt> operations.
-+     * It does not support the add or <tt>addAll</tt> operations.
-+     * <p/>
-+     * This implementation returns a <code>CompositeSet</code> which
-+     * composites the key sets from all of the composited maps.
-+     *
-+     * @return a set view of the keys contained in this map.
-+     */
-+    public Set keySet() {
-+        CompositeSet<K> keys = new CompositeSet<K>();
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            keys.addComposited(this.composite[i].keySet());
-+        }
-+        return keys;
-+    }
-+
-+    /**
-+     * Associates the specified value with the specified key in this map
-+     * (optional operation).  If the map previously contained a mapping for
-+     * this key, the old value is replaced by the specified value.  (A map
-+     * <tt>m</tt> is said to contain a mapping for a key <tt>k</tt> if and only
-+     * if {@link #containsKey(Object) m.containsKey(k)} would return
-+     * <tt>true</tt>.))
-+     *
-+     * @param key   key with which the specified value is to be associated.
-+     * @param value value to be associated with the specified key.
-+     * @return previous value associated with specified key, or <tt>null</tt>
-+     *         if there was no mapping for key.  A <tt>null</tt> return can
-+     *         also indicate that the map previously associated <tt>null</tt>
-+     *         with the specified key, if the implementation supports
-+     *         <tt>null</tt> values.
-+     * @throws UnsupportedOperationException if no MapMutator has been specified
-+     * @throws ClassCastException            if the class of the specified key or value
-+     *                                       prevents it from being stored in this map.
-+     * @throws IllegalArgumentException      if some aspect of this key or value
-+     *                                       prevents it from being stored in this map.
-+     * @throws NullPointerException          this map does not permit <tt>null</tt>
-+     *                                       keys or values, and the specified key or value is
-+     *                                       <tt>null</tt>.
-+     */
-+    public V put(K key, V value) {
-+        if (this.mutator == null) {
-+            throw new UnsupportedOperationException("No mutator specified");
-+        }
-+        return this.mutator.put(this, this.composite, key, value);
-+    }
-+
-+    /**
-+     * Copies all of the mappings from the specified map to this map
-+     * (optional operation).  The effect of this call is equivalent to that
-+     * of calling {@link #put(Object,Object) put(k, v)} on this map once
-+     * for each mapping from key <tt>k</tt> to value <tt>v</tt> in the
-+     * specified map.  The behavior of this operation is unspecified if the
-+     * specified map is modified while the operation is in progress.
-+     *
-+     * @param map Mappings to be stored in this map.
-+     * @throws UnsupportedOperationException if the <tt>putAll</tt> method is
-+     *                                       not supported by this map.
-+     * @throws ClassCastException            if the class of a key or value in the
-+     *                                       specified map prevents it from being stored in this map.
-+     * @throws IllegalArgumentException      some aspect of a key or value in the
-+     *                                       specified map prevents it from being stored in this map.
-+     * @throws NullPointerException          the specified map is <tt>null</tt>, or if
-+     *                                       this map does not permit <tt>null</tt> keys or values, and the
-+     *                                       specified map contains <tt>null</tt> keys or values.
-+     */
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        if (this.mutator == null) {
-+            throw new UnsupportedOperationException("No mutator specified");
-+        }
-+        this.mutator.putAll(this, this.composite, map);
-+    }
-+
-+    /**
-+     * Removes the mapping for this key from this map if it is present
-+     * (optional operation).   More formally, if this map contains a mapping
-+     * from key <tt>k</tt> to value <tt>v</tt> such that
-+     * <code>(key==null ?  k==null : key.equals(k))</code>, that mapping
-+     * is removed.  (The map can contain at most one such mapping.)
-+     * <p/>
-+     * <p>Returns the value to which the map previously associated the key, or
-+     * <tt>null</tt> if the map contained no mapping for this key.  (A
-+     * <tt>null</tt> return can also indicate that the map previously
-+     * associated <tt>null</tt> with the specified key if the implementation
-+     * supports <tt>null</tt> values.)  The map will not contain a mapping for
-+     * the specified  key once the call returns.
-+     *
-+     * @param key key whose mapping is to be removed from the map.
-+     * @return previous value associated with specified key, or <tt>null</tt>
-+     *         if there was no mapping for key.
-+     * @throws ClassCastException            if the key is of an inappropriate type for
-+     *                                       the composited map (optional).
-+     * @throws NullPointerException          if the key is <tt>null</tt> and the composited map
-+     *                                       does not not permit <tt>null</tt> keys (optional).
-+     * @throws UnsupportedOperationException if the <tt>remove</tt> method is
-+     *                                       not supported by the composited map containing the key
-+     */
-+    public V remove(Object key) {
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            if (this.composite[i].containsKey(key)) {
-+                return (V) this.composite[i].remove(key);
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Returns the number of key-value mappings in this map.  If the
-+     * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
-+     * <tt>Integer.MAX_VALUE</tt>.
-+     *
-+     * @return the number of key-value mappings in this map.
-+     */
-+    public int size() {
-+        int size = 0;
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            size += this.composite[i].size();
-+        }
-+        return size;
-+    }
-+
-+    /**
-+     * Returns a collection view of the values contained in this map.  The
-+     * collection is backed by the map, so changes to the map are reflected in
-+     * the collection, and vice-versa.  If the map is modified while an
-+     * iteration over the collection is in progress, the results of the
-+     * iteration are undefined.  The collection supports element removal,
-+     * which removes the corresponding mapping from the map, via the
-+     * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
-+     * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt> operations.
-+     * It does not support the add or <tt>addAll</tt> operations.
-+     *
-+     * @return a collection view of the values contained in this map.
-+     */
-+    public Collection<V> values() {
-+        CompositeCollection<V> keys = new CompositeCollection<V>();
-+        for (int i = this.composite.length - 1; i >= 0; --i) {
-+            keys.addComposited(this.composite[i].values());
-+        }
-+        return keys;
-+    }
-+
-+    /**
-+     * Checks if this Map equals another as per the Map specification.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if the maps are equal
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj instanceof Map) {
-+            Map map = (Map) obj;
-+            return (this.entrySet().equals(map.entrySet()));
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Gets a hash code for the Map as per the Map specification.
-+     */
-+    public int hashCode() {
-+        int code = 0;
-+        for (Iterator i = this.entrySet().iterator(); i.hasNext();) {
-+            code += i.next().hashCode();
-+        }
-+        return code;
-+    }
-+
-+    /**
-+     * This interface allows definition for all of the indeterminate
-+     * mutators in a CompositeMap, as well as providing a hook for
-+     * callbacks on key collisions.
-+     */
-+    public static interface MapMutator <K,V> {
-+        /**
-+         * Called when adding a new Composited Map results in a
-+         * key collision.
-+         *
-+         * @param composite the CompositeMap with the collision
-+         * @param existing  the Map already in the composite which contains the
-+         *                  offending key
-+         * @param added     the Map being added
-+         * @param intersect the intersection of the keysets of the existing and added maps
-+         */
-+        public void resolveCollision(CompositeMap<K, V> composite, Map<? extends K, ? extends V> existing, Map<? extends K, ? extends V> added, Collection<K> intersect);
-+
-+        /**
-+         * Called when the CompositeMap.put() method is invoked.
-+         *
-+         * @param map        the CompositeMap which is being modified
-+         * @param composited array of Maps in the CompositeMap being modified
-+         * @param key        key with which the specified value is to be associated.
-+         * @param value      value to be associated with the specified key.
-+         * @return previous value associated with specified key, or <tt>null</tt>
-+         *         if there was no mapping for key.  A <tt>null</tt> return can
-+         *         also indicate that the map previously associated <tt>null</tt>
-+         *         with the specified key, if the implementation supports
-+         *         <tt>null</tt> values.
-+         * @throws UnsupportedOperationException if not defined
-+         * @throws ClassCastException            if the class of the specified key or value
-+         *                                       prevents it from being stored in this map.
-+         * @throws IllegalArgumentException      if some aspect of this key or value
-+         *                                       prevents it from being stored in this map.
-+         * @throws NullPointerException          this map does not permit <tt>null</tt>
-+         *                                       keys or values, and the specified key or value is
-+         *                                       <tt>null</tt>.
-+         */
-+        public V put(CompositeMap<K, V> map, Map[] composited, K key, V value);
-+
-+        /**
-+         * Called when the CompositeMap.putAll() method is invoked.
-+         *
-+         * @param map        the CompositeMap which is being modified
-+         * @param composited array of Maps in the CompositeMap being modified
-+         * @param mapToAdd   Mappings to be stored in this CompositeMap
-+         * @throws UnsupportedOperationException if not defined
-+         * @throws ClassCastException            if the class of the specified key or value
-+         *                                       prevents it from being stored in this map.
-+         * @throws IllegalArgumentException      if some aspect of this key or value
-+         *                                       prevents it from being stored in this map.
-+         * @throws NullPointerException          this map does not permit <tt>null</tt>
-+         *                                       keys or values, and the specified key or value is
-+         *                                       <tt>null</tt>.
-+         */
-+        public void putAll(CompositeMap<K, V> map, Map[] composited, Map<? extends K, ? extends V> mapToAdd);
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/FastHashMap.java
-@@ -0,0 +1,711 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.util.*;
-+
-+/**
-+ * <p>A customized implementation of <code>java.util.HashMap</code> designed
-+ * to operate in a multithreaded environment where the large majority of
-+ * method calls are read-only, instead of structural changes.  When operating
-+ * in "fast" mode, read calls are non-synchronized and write calls perform the
-+ * following steps:</p>
-+ * <ul>
-+ * <li>Clone the existing collection
-+ * <li>Perform the modification on the clone
-+ * <li>Replace the existing collection with the (modified) clone
-+ * </ul>
-+ * <p>When first created, objects of this class default to "slow" mode, where
-+ * all accesses of any type are synchronized but no cloning takes place.  This
-+ * is appropriate for initially populating the collection, followed by a switch
-+ * to "fast" mode (by calling <code>setFast(true)</code>) after initialization
-+ * is complete.</p>
-+ * <p/>
-+ * <p><strong>NOTE</strong>: If you are creating and accessing a
-+ * <code>HashMap</code> only within a single thread, you should use
-+ * <code>java.util.HashMap</code> directly (with no synchronization), for
-+ * maximum performance.</p>
-+ * <p/>
-+ * <p><strong>NOTE</strong>: <i>This class is not cross-platform.
-+ * Using it may cause unexpected failures on some architectures.</i>
-+ * It suffers from the same problems as the double-checked locking idiom.
-+ * In particular, the instruction that clones the internal collection and the
-+ * instruction that sets the internal reference to the clone can be executed
-+ * or perceived out-of-order.  This means that any read operation might fail
-+ * unexpectedly, as it may be reading the state of the internal collection
-+ * before the internal collection is fully formed.
-+ * For more information on the double-checked locking idiom, see the
-+ * <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">
-+ * Double-Checked Locking Idiom Is Broken Declaration</a>.</p>
-+ *
-+ * @author Craig R. McClanahan
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 1.0
-+ */
-+public class FastHashMap <K,V> extends HashMap<K, V> {
-+
-+    /**
-+     * The underlying map we are managing.
-+     */
-+    protected HashMap<K, V> map = null;
-+
-+    /**
-+     * Are we currently operating in "fast" mode?
-+     */
-+    protected boolean fast = false;
-+
-+    // Constructors
-+    // ----------------------------------------------------------------------
-+
-+    /**
-+     * Construct an empty map.
-+     */
-+    public FastHashMap() {
-+        super();
-+        this.map = new HashMap<K, V>();
-+    }
-+
-+    /**
-+     * Construct an empty map with the specified capacity.
-+     *
-+     * @param capacity the initial capacity of the empty map
-+     */
-+    public FastHashMap(int capacity) {
-+        super();
-+        this.map = new HashMap<K, V>(capacity);
-+    }
-+
-+    /**
-+     * Construct an empty map with the specified capacity and load factor.
-+     *
-+     * @param capacity the initial capacity of the empty map
-+     * @param factor   the load factor of the new map
-+     */
-+    public FastHashMap(int capacity, float factor) {
-+        super();
-+        this.map = new HashMap<K, V>(capacity, factor);
-+    }
-+
-+    /**
-+     * Construct a new map with the same mappings as the specified map.
-+     *
-+     * @param map the map whose mappings are to be copied
-+     */
-+    public FastHashMap(Map map) {
-+        super();
-+        this.map = new HashMap<K, V>(map);
-+    }
-+
-+
-+    // Property access
-+    // ----------------------------------------------------------------------
-+
-+    /**
-+     * Returns true if this map is operating in fast mode.
-+     *
-+     * @return true if this map is operating in fast mode
-+     */
-+    public boolean getFast() {
-+        return (this.fast);
-+    }
-+
-+    /**
-+     * Sets whether this map is operating in fast mode.
-+     *
-+     * @param fast true if this map should operate in fast mode
-+     */
-+    public void setFast(boolean fast) {
-+        this.fast = fast;
-+    }
-+
-+
-+    // Map access
-+    // ----------------------------------------------------------------------
-+    // These methods can forward straight to the wrapped Map in 'fast' mode.
-+    // (because they are query methods)
-+
-+    /**
-+     * Return the value to which this map maps the specified key.  Returns
-+     * <code>null</code> if the map contains no mapping for this key, or if
-+     * there is a mapping with a value of <code>null</code>.  Use the
-+     * <code>containsKey()</code> method to disambiguate these cases.
-+     *
-+     * @param key the key whose value is to be returned
-+     * @return the value mapped to that key, or null
-+     */
-+    public V get(Object key) {
-+        if (fast) {
-+            return (map.get(key));
-+        } else {
-+            synchronized (map) {
-+                return (map.get(key));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return the number of key-value mappings in this map.
-+     *
-+     * @return the current size of the map
-+     */
-+    public int size() {
-+        if (fast) {
-+            return (map.size());
-+        } else {
-+            synchronized (map) {
-+                return (map.size());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return <code>true</code> if this map contains no mappings.
-+     *
-+     * @return is the map currently empty
-+     */
-+    public boolean isEmpty() {
-+        if (fast) {
-+            return (map.isEmpty());
-+        } else {
-+            synchronized (map) {
-+                return (map.isEmpty());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return <code>true</code> if this map contains a mapping for the
-+     * specified key.
-+     *
-+     * @param key the key to be searched for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsKey(Object key) {
-+        if (fast) {
-+            return (map.containsKey(key));
-+        } else {
-+            synchronized (map) {
-+                return (map.containsKey(key));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return <code>true</code> if this map contains one or more keys mapping
-+     * to the specified value.
-+     *
-+     * @param value the value to be searched for
-+     * @return true if the map contains the value
-+     */
-+    public boolean containsValue(Object value) {
-+        if (fast) {
-+            return (map.containsValue(value));
-+        } else {
-+            synchronized (map) {
-+                return (map.containsValue(value));
-+            }
-+        }
-+    }
-+
-+    // Map modification
-+    // ----------------------------------------------------------------------
-+    // These methods perform special behaviour in 'fast' mode.
-+    // The map is cloned, updated and then assigned back.
-+    // See the comments at the top as to why this won't always work.
-+
-+    /**
-+     * Associate the specified value with the specified key in this map.
-+     * If the map previously contained a mapping for this key, the old
-+     * value is replaced and returned.
-+     *
-+     * @param key   the key with which the value is to be associated
-+     * @param value the value to be associated with this key
-+     * @return the value previously mapped to the key, or null
-+     */
-+    public V put(K key, V value) {
-+        if (fast) {
-+            synchronized (this) {
-+                HashMap<K, V> temp = (HashMap<K, V>) map.clone();
-+                V result = temp.put(key, value);
-+                map = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (map) {
-+                return (map.put(key, value));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Copy all of the mappings from the specified map to this one, replacing
-+     * any mappings with the same keys.
-+     *
-+     * @param in the map whose mappings are to be copied
-+     */
-+    public void putAll(Map<? extends K, ? extends V> in) {
-+        if (fast) {
-+            synchronized (this) {
-+                HashMap<K, V> temp = (HashMap<K, V>) map.clone();
-+                temp.putAll(in);
-+                map = temp;
-+            }
-+        } else {
-+            synchronized (map) {
-+                map.putAll(in);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Remove any mapping for this key, and return any previously
-+     * mapped value.
-+     *
-+     * @param key the key whose mapping is to be removed
-+     * @return the value removed, or null
-+     */
-+    public V remove(Object key) {
-+        if (fast) {
-+            synchronized (this) {
-+                HashMap<K, V> temp = (HashMap<K, V>) map.clone();
-+                V result = temp.remove(key);
-+                map = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (map) {
-+                return (map.remove(key));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Remove all mappings from this map.
-+     */
-+    public void clear() {
-+        if (fast) {
-+            synchronized (this) {
-+                map = new HashMap<K, V>();
-+            }
-+        } else {
-+            synchronized (map) {
-+                map.clear();
-+            }
-+        }
-+    }
-+
-+    // Basic object methods
-+    // ----------------------------------------------------------------------
-+    
-+    /**
-+     * Compare the specified object with this list for equality.  This
-+     * implementation uses exactly the code that is used to define the
-+     * list equals function in the documentation for the
-+     * <code>Map.equals</code> method.
-+     *
-+     * @param o the object to be compared to this list
-+     * @return true if the two maps are equal
-+     */
-+    public boolean equals(Object o) {
-+        // Simple tests that require no synchronization
-+        if (o == this) {
-+            return (true);
-+        } else if (!(o instanceof Map)) {
-+            return (false);
-+        }
-+        Map mo = (Map) o;
-+
-+        // Compare the two maps for equality
-+        if (fast) {
-+            if (mo.size() != map.size()) {
-+                return (false);
-+            }
-+            Iterator i = map.entrySet().iterator();
-+            while (i.hasNext()) {
-+                Map.Entry e = (Map.Entry) i.next();
-+                Object key = e.getKey();
-+                Object value = e.getValue();
-+                if (value == null) {
-+                    if (!(mo.get(key) == null && mo.containsKey(key))) {
-+                        return (false);
-+                    }
-+                } else {
-+                    if (!value.equals(mo.get(key))) {
-+                        return (false);
-+                    }
-+                }
-+            }
-+            return (true);
-+
-+        } else {
-+            synchronized (map) {
-+                if (mo.size() != map.size()) {
-+                    return (false);
-+                }
-+                Iterator i = map.entrySet().iterator();
-+                while (i.hasNext()) {
-+                    Map.Entry e = (Map.Entry) i.next();
-+                    Object key = e.getKey();
-+                    Object value = e.getValue();
-+                    if (value == null) {
-+                        if (!(mo.get(key) == null && mo.containsKey(key))) {
-+                            return (false);
-+                        }
-+                    } else {
-+                        if (!value.equals(mo.get(key))) {
-+                            return (false);
-+                        }
-+                    }
-+                }
-+                return (true);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return the hash code value for this map.  This implementation uses
-+     * exactly the code that is used to define the list hash function in the
-+     * documentation for the <code>Map.hashCode</code> method.
-+     *
-+     * @return suitable integer hash code
-+     */
-+    public int hashCode() {
-+        if (fast) {
-+            int h = 0;
-+            Iterator<Map.Entry<K, V>> i = map.entrySet().iterator();
-+            while (i.hasNext()) {
-+                h += i.next().hashCode();
-+            }
-+            return (h);
-+        } else {
-+            synchronized (map) {
-+                int h = 0;
-+                Iterator<Map.Entry<K, V>> i = map.entrySet().iterator();
-+                while (i.hasNext()) {
-+                    h += i.next().hashCode();
-+                }
-+                return (h);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return a shallow copy of this <code>FastHashMap</code> instance.
-+     * The keys and values themselves are not copied.
-+     *
-+     * @return a clone of this map
-+     */
-+    public FastHashMap<K, V> clone() {
-+        FastHashMap<K, V> results = null;
-+        if (fast) {
-+            results = new FastHashMap<K, V>(map);
-+        } else {
-+            synchronized (map) {
-+                results = new FastHashMap<K, V>(map);
-+            }
-+        }
-+        results.setFast(getFast());
-+        return (results);
-+    }
-+
-+    // Map views
-+    // ----------------------------------------------------------------------
-+    
-+    /**
-+     * Return a collection view of the mappings contained in this map.  Each
-+     * element in the returned collection is a <code>Map.Entry</code>.
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        return new EntrySet();
-+    }
-+
-+    /**
-+     * Return a set view of the keys contained in this map.
-+     */
-+    public Set<K> keySet() {
-+        return new KeySet();
-+    }
-+
-+    /**
-+     * Return a collection view of the values contained in this map.
-+     */
-+    public Collection<V> values() {
-+        return new Values();
-+    }
-+
-+    // Map view inner classes
-+    // ----------------------------------------------------------------------
-+
-+    /**
-+     * Abstract collection implementation shared by keySet(), values() and entrySet().
-+     */
-+    private abstract class CollectionView <E> implements Collection<E> {
-+
-+        public CollectionView() {
-+        }
-+
-+        protected abstract Collection<E> get(Map<K, V> map);
-+
-+        protected abstract E iteratorNext(Map.Entry<K, V> entry);
-+
-+
-+        public void clear() {
-+            if (fast) {
-+                synchronized (FastHashMap.this) {
-+                    map = new HashMap<K, V>();
-+                }
-+            } else {
-+                synchronized (map) {
-+                    get(map).clear();
-+                }
-+            }
-+        }
-+
-+        public boolean remove(Object o) {
-+            if (fast) {
-+                synchronized (FastHashMap.this) {
-+                    HashMap temp = (HashMap) map.clone();
-+                    boolean r = get(temp).remove(o);
-+                    map = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (map) {
-+                    return get(map).remove(o);
-+                }
-+            }
-+        }
-+
-+        public boolean removeAll(Collection<?> o) {
-+            if (fast) {
-+                synchronized (FastHashMap.this) {
-+                    HashMap temp = (HashMap) map.clone();
-+                    boolean r = get(temp).removeAll(o);
-+                    map = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (map) {
-+                    return get(map).removeAll(o);
-+                }
-+            }
-+        }
-+
-+        public boolean retainAll(Collection<?> o) {
-+            if (fast) {
-+                synchronized (FastHashMap.this) {
-+                    HashMap temp = (HashMap) map.clone();
-+                    boolean r = get(temp).retainAll(o);
-+                    map = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (map) {
-+                    return get(map).retainAll(o);
-+                }
-+            }
-+        }
-+
-+        public int size() {
-+            if (fast) {
-+                return get(map).size();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).size();
-+                }
-+            }
-+        }
-+
-+
-+        public boolean isEmpty() {
-+            if (fast) {
-+                return get(map).isEmpty();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).isEmpty();
-+                }
-+            }
-+        }
-+
-+        public boolean contains(Object o) {
-+            if (fast) {
-+                return get(map).contains(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).contains(o);
-+                }
-+            }
-+        }
-+
-+        public boolean containsAll(Collection<?> o) {
-+            if (fast) {
-+                return get(map).containsAll(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).containsAll(o);
-+                }
-+            }
-+        }
-+
-+        public <T> T[] toArray(T[] o) {
-+            if (fast) {
-+                return get(map).toArray(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).toArray(o);
-+                }
-+            }
-+        }
-+
-+        public Object[] toArray() {
-+            if (fast) {
-+                return get(map).toArray();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).toArray();
-+                }
-+            }
-+        }
-+
-+
-+        public boolean equals(Object o) {
-+            if (o == this) return true;
-+            if (fast) {
-+                return get(map).equals(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).equals(o);
-+                }
-+            }
-+        }
-+
-+        public int hashCode() {
-+            if (fast) {
-+                return get(map).hashCode();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).hashCode();
-+                }
-+            }
-+        }
-+
-+        public boolean add(E o) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public boolean addAll(Collection<? extends E> c) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public Iterator<E> iterator() {
-+            return new CollectionViewIterator();
-+        }
-+
-+        private class CollectionViewIterator implements Iterator<E> {
-+
-+            private Map expected;
-+            private Map.Entry lastReturned = null;
-+            private Iterator iterator;
-+
-+            public CollectionViewIterator() {
-+                this.expected = map;
-+                this.iterator = expected.entrySet().iterator();
-+            }
-+
-+            public boolean hasNext() {
-+                if (expected != map) {
-+                    throw new ConcurrentModificationException();
-+                }
-+                return iterator.hasNext();
-+            }
-+
-+            public E next() {
-+                if (expected != map) {
-+                    throw new ConcurrentModificationException();
-+                }
-+                lastReturned = (Map.Entry) iterator.next();
-+                return iteratorNext(lastReturned);
-+            }
-+
-+            public void remove() {
-+                if (lastReturned == null) {
-+                    throw new IllegalStateException();
-+                }
-+                if (fast) {
-+                    synchronized (FastHashMap.this) {
-+                        if (expected != map) {
-+                            throw new ConcurrentModificationException();
-+                        }
-+                        FastHashMap.this.remove(lastReturned.getKey());
-+                        lastReturned = null;
-+                        expected = map;
-+                    }
-+                } else {
-+                    iterator.remove();
-+                    lastReturned = null;
-+                }
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Set implementation over the keys of the FastHashMap
-+     */
-+    private class KeySet extends CollectionView<K> implements Set<K> {
-+
-+        protected Collection get(Map<K, V> map) {
-+            return map.keySet();
-+        }
-+
-+        protected K iteratorNext(Map.Entry<K, V> entry) {
-+            return entry.getKey();
-+        }
-+
-+
-+    }
-+
-+    /**
-+     * Collection implementation over the values of the FastHashMap
-+     */
-+    private class Values extends CollectionView<V> {
-+
-+        protected Collection get(Map<K, V> map) {
-+            return map.values();
-+        }
-+
-+        protected V iteratorNext(Map.Entry<K, V> entry) {
-+            return entry.getValue();
-+        }
-+    }
-+
-+    /**
-+     * Set implementation over the entries of the FastHashMap
-+     */
-+    private class EntrySet extends CollectionView<Map.Entry<K, V>> implements Set<Map.Entry<K, V>> {
-+
-+        protected Collection get(Map<K, V> map) {
-+            return map.entrySet();
-+        }
-+
-+        protected Map.Entry<K, V> iteratorNext(Map.Entry<K, V> entry) {
-+            return entry;
-+        }
-+
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/FastTreeMap.java
-@@ -0,0 +1,817 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.util.*;
-+
-+/**
-+ * <p>A customized implementation of <code>java.util.TreeMap</code> designed
-+ * to operate in a multithreaded environment where the large majority of
-+ * method calls are read-only, instead of structural changes.  When operating
-+ * in "fast" mode, read calls are non-synchronized and write calls perform the
-+ * following steps:</p>
-+ * <ul>
-+ * <li>Clone the existing collection
-+ * <li>Perform the modification on the clone
-+ * <li>Replace the existing collection with the (modified) clone
-+ * </ul>
-+ * <p>When first created, objects of this class default to "slow" mode, where
-+ * all accesses of any type are synchronized but no cloning takes place.  This
-+ * is appropriate for initially populating the collection, followed by a switch
-+ * to "fast" mode (by calling <code>setFast(true)</code>) after initialization
-+ * is complete.</p>
-+ * <p/>
-+ * <p><strong>NOTE</strong>: If you are creating and accessing a
-+ * <code>TreeMap</code> only within a single thread, you should use
-+ * <code>java.util.TreeMap</code> directly (with no synchronization), for
-+ * maximum performance.</p>
-+ * <p/>
-+ * <p><strong>NOTE</strong>: <i>This class is not cross-platform.
-+ * Using it may cause unexpected failures on some architectures.</i>
-+ * It suffers from the same problems as the double-checked locking idiom.
-+ * In particular, the instruction that clones the internal collection and the
-+ * instruction that sets the internal reference to the clone can be executed
-+ * or perceived out-of-order.  This means that any read operation might fail
-+ * unexpectedly, as it may be reading the state of the internal collection
-+ * before the internal collection is fully formed.
-+ * For more information on the double-checked locking idiom, see the
-+ * <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">
-+ * Double-Checked Locking Idiom Is Broken Declaration</a>.</p>
-+ *
-+ * @author Craig R. McClanahan
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 1.0
-+ */
-+public class FastTreeMap <K,V> extends TreeMap<K, V> {
-+
-+    /**
-+     * The underlying map we are managing.
-+     */
-+    protected TreeMap<K, V> map = null;
-+
-+    /**
-+     * Are we operating in "fast" mode?
-+     */
-+    protected boolean fast = false;
-+
-+
-+    // Constructors
-+    // ----------------------------------------------------------------------
-+
-+    /**
-+     * Construct a an empty map.
-+     */
-+    public FastTreeMap() {
-+        super();
-+        this.map = new TreeMap<K, V>();
-+    }
-+
-+    /**
-+     * Construct an empty map with the specified comparator.
-+     *
-+     * @param comparator the comparator to use for ordering tree elements
-+     */
-+    public FastTreeMap(Comparator<K> comparator) {
-+        super();
-+        this.map = new TreeMap<K, V>(comparator);
-+    }
-+
-+    /**
-+     * Construct a new map with the same mappings as the specified map,
-+     * sorted according to the keys's natural order
-+     *
-+     * @param map the map whose mappings are to be copied
-+     */
-+    public FastTreeMap(Map<K, V> map) {
-+        super();
-+        this.map = new TreeMap<K, V>(map);
-+    }
-+
-+    /**
-+     * Construct a new map with the same mappings as the specified map,
-+     * sorted according to the same ordering
-+     *
-+     * @param map the map whose mappings are to be copied
-+     */
-+    public FastTreeMap(SortedMap<K, V> map) {
-+        super();
-+        this.map = new TreeMap<K, V>(map);
-+    }
-+
-+
-+    // Property access
-+    // ----------------------------------------------------------------------
-+
-+    /**
-+     * Returns true if this map is operating in fast mode.
-+     *
-+     * @return true if this map is operating in fast mode
-+     */
-+    public boolean getFast() {
-+        return (this.fast);
-+    }
-+
-+    /**
-+     * Sets whether this map is operating in fast mode.
-+     *
-+     * @param fast true if this map should operate in fast mode
-+     */
-+    public void setFast(boolean fast) {
-+        this.fast = fast;
-+    }
-+
-+
-+    // Map access
-+    // ----------------------------------------------------------------------
-+    // These methods can forward straight to the wrapped Map in 'fast' mode.
-+    // (because they are query methods)
-+
-+    /**
-+     * Return the value to which this map maps the specified key.  Returns
-+     * <code>null</code> if the map contains no mapping for this key, or if
-+     * there is a mapping with a value of <code>null</code>.  Use the
-+     * <code>containsKey()</code> method to disambiguate these cases.
-+     *
-+     * @param key the key whose value is to be returned
-+     * @return the value mapped to that key, or null
-+     */
-+    public V get(Object key) {
-+        if (fast) {
-+            return (map.get(key));
-+        } else {
-+            synchronized (map) {
-+                return (map.get(key));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return the number of key-value mappings in this map.
-+     *
-+     * @return the current size of the map
-+     */
-+    public int size() {
-+        if (fast) {
-+            return (map.size());
-+        } else {
-+            synchronized (map) {
-+                return (map.size());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return <code>true</code> if this map contains no mappings.
-+     *
-+     * @return is the map currently empty
-+     */
-+    public boolean isEmpty() {
-+        if (fast) {
-+            return (map.isEmpty());
-+        } else {
-+            synchronized (map) {
-+                return (map.isEmpty());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return <code>true</code> if this map contains a mapping for the
-+     * specified key.
-+     *
-+     * @param key the key to be searched for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsKey(Object key) {
-+        if (fast) {
-+            return (map.containsKey(key));
-+        } else {
-+            synchronized (map) {
-+                return (map.containsKey(key));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return <code>true</code> if this map contains one or more keys mapping
-+     * to the specified value.
-+     *
-+     * @param value the value to be searched for
-+     * @return true if the map contains the value
-+     */
-+    public boolean containsValue(Object value) {
-+        if (fast) {
-+            return (map.containsValue(value));
-+        } else {
-+            synchronized (map) {
-+                return (map.containsValue(value));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return the comparator used to order this map, or <code>null</code>
-+     * if this map uses its keys' natural order.
-+     *
-+     * @return the comparator used to order the map, or null if natural order
-+     */
-+    public Comparator<? super K> comparator() {
-+        if (fast) {
-+            return (map.comparator());
-+        } else {
-+            synchronized (map) {
-+                return (map.comparator());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return the first (lowest) key currently in this sorted map.
-+     *
-+     * @return the first key in the map
-+     */
-+    public K firstKey() {
-+        if (fast) {
-+            return (map.firstKey());
-+        } else {
-+            synchronized (map) {
-+                return (map.firstKey());
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return the last (highest) key currently in this sorted map.
-+     *
-+     * @return the last key in the map
-+     */
-+    public K lastKey() {
-+        if (fast) {
-+            return (map.lastKey());
-+        } else {
-+            synchronized (map) {
-+                return (map.lastKey());
-+            }
-+        }
-+    }
-+
-+
-+    // Map modification
-+    // ----------------------------------------------------------------------
-+    // These methods perform special behaviour in 'fast' mode.
-+    // The map is cloned, updated and then assigned back.
-+    // See the comments at the top as to why this won't always work.
-+
-+    /**
-+     * Associate the specified value with the specified key in this map.
-+     * If the map previously contained a mapping for this key, the old
-+     * value is replaced and returned.
-+     *
-+     * @param key   the key with which the value is to be associated
-+     * @param value the value to be associated with this key
-+     * @return the value previously mapped to the key, or null
-+     */
-+    public V put(K key, V value) {
-+        if (fast) {
-+            synchronized (this) {
-+                TreeMap<K, V> temp = (TreeMap<K, V>) map.clone();
-+                V result = temp.put(key, value);
-+                map = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (map) {
-+                return (map.put(key, value));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Copy all of the mappings from the specified map to this one, replacing
-+     * any mappings with the same keys.
-+     *
-+     * @param in the map whose mappings are to be copied
-+     */
-+    public void putAll(Map<? extends K, ? extends V> in) {
-+        if (fast) {
-+            synchronized (this) {
-+                TreeMap<K, V> temp = (TreeMap<K, V>) map.clone();
-+                temp.putAll(in);
-+                map = temp;
-+            }
-+        } else {
-+            synchronized (map) {
-+                map.putAll(in);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Remove any mapping for this key, and return any previously
-+     * mapped value.
-+     *
-+     * @param key the key whose mapping is to be removed
-+     * @return the value removed, or null
-+     */
-+    public V remove(Object key) {
-+        if (fast) {
-+            synchronized (this) {
-+                TreeMap<K, V> temp = (TreeMap<K, V>) map.clone();
-+                V result = temp.remove(key);
-+                map = temp;
-+                return (result);
-+            }
-+        } else {
-+            synchronized (map) {
-+                return (map.remove(key));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Remove all mappings from this map.
-+     */
-+    public void clear() {
-+        if (fast) {
-+            synchronized (this) {
-+                map = new TreeMap<K, V>();
-+            }
-+        } else {
-+            synchronized (map) {
-+                map.clear();
-+            }
-+        }
-+    }
-+    
-+    
-+    // Basic object methods
-+    // ----------------------------------------------------------------------
-+    
-+    /**
-+     * Compare the specified object with this list for equality.  This
-+     * implementation uses exactly the code that is used to define the
-+     * list equals function in the documentation for the
-+     * <code>Map.equals</code> method.
-+     *
-+     * @param o the object to be compared to this list
-+     * @return true if the two maps are equal
-+     */
-+    public boolean equals(Object o) {
-+        // Simple tests that require no synchronization
-+        if (o == this) {
-+            return (true);
-+        } else if (!(o instanceof Map)) {
-+            return (false);
-+        }
-+        Map mo = (Map) o;
-+
-+        // Compare the two maps for equality
-+        if (fast) {
-+            if (mo.size() != map.size()) {
-+                return (false);
-+            }
-+            Iterator i = map.entrySet().iterator();
-+            while (i.hasNext()) {
-+                Map.Entry e = (Map.Entry) i.next();
-+                Object key = e.getKey();
-+                Object value = e.getValue();
-+                if (value == null) {
-+                    if (!(mo.get(key) == null && mo.containsKey(key))) {
-+                        return (false);
-+                    }
-+                } else {
-+                    if (!value.equals(mo.get(key))) {
-+                        return (false);
-+                    }
-+                }
-+            }
-+            return (true);
-+        } else {
-+            synchronized (map) {
-+                if (mo.size() != map.size()) {
-+                    return (false);
-+                }
-+                Iterator i = map.entrySet().iterator();
-+                while (i.hasNext()) {
-+                    Map.Entry e = (Map.Entry) i.next();
-+                    Object key = e.getKey();
-+                    Object value = e.getValue();
-+                    if (value == null) {
-+                        if (!(mo.get(key) == null && mo.containsKey(key))) {
-+                            return (false);
-+                        }
-+                    } else {
-+                        if (!value.equals(mo.get(key))) {
-+                            return (false);
-+                        }
-+                    }
-+                }
-+                return (true);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return the hash code value for this map.  This implementation uses
-+     * exactly the code that is used to define the list hash function in the
-+     * documentation for the <code>Map.hashCode</code> method.
-+     *
-+     * @return a suitable integer hash code
-+     */
-+    public int hashCode() {
-+        if (fast) {
-+            int h = 0;
-+            Iterator i = map.entrySet().iterator();
-+            while (i.hasNext()) {
-+                h += i.next().hashCode();
-+            }
-+            return (h);
-+        } else {
-+            synchronized (map) {
-+                int h = 0;
-+                Iterator i = map.entrySet().iterator();
-+                while (i.hasNext()) {
-+                    h += i.next().hashCode();
-+                }
-+                return (h);
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return a shallow copy of this <code>FastTreeMap</code> instance.
-+     * The keys and values themselves are not copied.
-+     *
-+     * @return a clone of this map
-+     */
-+    public FastTreeMap<K, V> clone() {
-+        FastTreeMap results = null;
-+        if (fast) {
-+            results = new FastTreeMap(map);
-+        } else {
-+            synchronized (map) {
-+                results = new FastTreeMap(map);
-+            }
-+        }
-+        results.setFast(getFast());
-+        return (results);
-+    }
-+
-+
-+    // Sub map views
-+    // ----------------------------------------------------------------------
-+    
-+    /**
-+     * Return a view of the portion of this map whose keys are strictly
-+     * less than the specified key.
-+     *
-+     * @param key Key higher than any in the returned map
-+     * @return a head map
-+     */
-+    public SortedMap<K, V> headMap(K key) {
-+        if (fast) {
-+            return (map.headMap(key));
-+        } else {
-+            synchronized (map) {
-+                return (map.headMap(key));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return a view of the portion of this map whose keys are in the
-+     * range fromKey (inclusive) to toKey (exclusive).
-+     *
-+     * @param fromKey Lower limit of keys for the returned map
-+     * @param toKey   Upper limit of keys for the returned map
-+     * @return a sub map
-+     */
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        if (fast) {
-+            return (map.subMap(fromKey, toKey));
-+        } else {
-+            synchronized (map) {
-+                return (map.subMap(fromKey, toKey));
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Return a view of the portion of this map whose keys are greater than
-+     * or equal to the specified key.
-+     *
-+     * @param key Key less than or equal to any in the returned map
-+     * @return a tail map
-+     */
-+    public SortedMap<K, V> tailMap(K key) {
-+        if (fast) {
-+            return (map.tailMap(key));
-+        } else {
-+            synchronized (map) {
-+                return (map.tailMap(key));
-+            }
-+        }
-+    }
-+
-+
-+    // Map views
-+    // ----------------------------------------------------------------------
-+    
-+    /**
-+     * Return a collection view of the mappings contained in this map.  Each
-+     * element in the returned collection is a <code>Map.Entry</code>.
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        return new EntrySet();
-+    }
-+
-+    /**
-+     * Return a set view of the keys contained in this map.
-+     */
-+    public Set<K> keySet() {
-+        return new KeySet();
-+    }
-+
-+    /**
-+     * Return a collection view of the values contained in this map.
-+     */
-+    public Collection<V> values() {
-+        return new Values();
-+    }
-+
-+    // Map view inner classes
-+    // ----------------------------------------------------------------------
-+
-+    /**
-+     * Abstract collection implementation shared by keySet(), values() and entrySet().
-+     */
-+    private abstract class CollectionView <E> implements Collection<E> {
-+
-+        public CollectionView() {
-+        }
-+
-+        protected abstract Collection<E> get(Map<K, V> map);
-+
-+        protected abstract E iteratorNext(Map.Entry<K, V> entry);
-+
-+
-+        public void clear() {
-+            if (fast) {
-+                synchronized (FastTreeMap.this) {
-+                    map = new TreeMap<K, V>();
-+                }
-+            } else {
-+                synchronized (map) {
-+                    get(map).clear();
-+                }
-+            }
-+        }
-+
-+        public boolean remove(Object o) {
-+            if (fast) {
-+                synchronized (FastTreeMap.this) {
-+                    TreeMap<K, V> temp = (TreeMap<K, V>) map.clone();
-+                    boolean r = get(temp).remove(o);
-+                    map = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (map) {
-+                    return get(map).remove(o);
-+                }
-+            }
-+        }
-+
-+        public boolean removeAll(Collection<?> o) {
-+            if (fast) {
-+                synchronized (FastTreeMap.this) {
-+                    TreeMap temp = (TreeMap) map.clone();
-+                    boolean r = get(temp).removeAll(o);
-+                    map = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (map) {
-+                    return get(map).removeAll(o);
-+                }
-+            }
-+        }
-+
-+        public boolean retainAll(Collection<?> o) {
-+            if (fast) {
-+                synchronized (FastTreeMap.this) {
-+                    TreeMap temp = (TreeMap) map.clone();
-+                    boolean r = get(temp).retainAll(o);
-+                    map = temp;
-+                    return r;
-+                }
-+            } else {
-+                synchronized (map) {
-+                    return get(map).retainAll(o);
-+                }
-+            }
-+        }
-+
-+        public int size() {
-+            if (fast) {
-+                return get(map).size();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).size();
-+                }
-+            }
-+        }
-+
-+
-+        public boolean isEmpty() {
-+            if (fast) {
-+                return get(map).isEmpty();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).isEmpty();
-+                }
-+            }
-+        }
-+
-+        public boolean contains(Object o) {
-+            if (fast) {
-+                return get(map).contains(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).contains(o);
-+                }
-+            }
-+        }
-+
-+        public boolean containsAll(Collection<?> o) {
-+            if (fast) {
-+                return get(map).containsAll(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).containsAll(o);
-+                }
-+            }
-+        }
-+
-+        public <T> T[] toArray(T[] o) {
-+            if (fast) {
-+                return get(map).toArray(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).toArray(o);
-+                }
-+            }
-+        }
-+
-+        public Object[] toArray() {
-+            if (fast) {
-+                return get(map).toArray();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).toArray();
-+                }
-+            }
-+        }
-+
-+
-+        public boolean equals(Object o) {
-+            if (o == this) return true;
-+            if (fast) {
-+                return get(map).equals(o);
-+            } else {
-+                synchronized (map) {
-+                    return get(map).equals(o);
-+                }
-+            }
-+        }
-+
-+        public int hashCode() {
-+            if (fast) {
-+                return get(map).hashCode();
-+            } else {
-+                synchronized (map) {
-+                    return get(map).hashCode();
-+                }
-+            }
-+        }
-+
-+        public boolean add(E o) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public boolean addAll(Collection<? extends E> c) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public Iterator<E> iterator() {
-+            return new CollectionViewIterator();
-+        }
-+
-+        private class CollectionViewIterator implements Iterator<E> {
-+
-+            private Map<K, V> expected;
-+            private Map.Entry<K, V> lastReturned = null;
-+            private Iterator<Map.Entry<K, V>> iterator;
-+
-+            public CollectionViewIterator() {
-+                this.expected = map;
-+                this.iterator = expected.entrySet().iterator();
-+            }
-+
-+            public boolean hasNext() {
-+                if (expected != map) {
-+                    throw new ConcurrentModificationException();
-+                }
-+                return iterator.hasNext();
-+            }
-+
-+            public E next() {
-+                if (expected != map) {
-+                    throw new ConcurrentModificationException();
-+                }
-+                lastReturned = (Map.Entry<K, V>) iterator.next();
-+                return iteratorNext(lastReturned);
-+            }
-+
-+            public void remove() {
-+                if (lastReturned == null) {
-+                    throw new IllegalStateException();
-+                }
-+                if (fast) {
-+                    synchronized (FastTreeMap.this) {
-+                        if (expected != map) {
-+                            throw new ConcurrentModificationException();
-+                        }
-+                        FastTreeMap.this.remove(lastReturned.getKey());
-+                        lastReturned = null;
-+                        expected = map;
-+                    }
-+                } else {
-+                    iterator.remove();
-+                    lastReturned = null;
-+                }
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Set implementation over the keys of the FastTreeMap
-+     */
-+    private class KeySet extends CollectionView<K> implements Set<K> {
-+
-+        protected Collection<K> get(Map<K, V> map) {
-+            return map.keySet();
-+        }
-+
-+        protected K iteratorNext(Map.Entry<K, V> entry) {
-+            return entry.getKey();
-+        }
-+
-+    }
-+
-+    /**
-+     * Collection implementation over the values of the FastTreeMap
-+     */
-+    private class Values extends CollectionView<V> {
-+
-+        protected Collection<V> get(Map<K, V> map) {
-+            return map.values();
-+        }
-+
-+        protected V iteratorNext(Map.Entry<K, V> entry) {
-+            return entry.getValue();
-+        }
-+    }
-+
-+    /**
-+     * Set implementation over the entries of the FastTreeMap
-+     */
-+    private class EntrySet extends CollectionView<Map.Entry<K, V>> implements Set<Map.Entry<K, V>> {
-+
-+        protected Collection<Map.Entry<K, V>> get(Map<K, V> map) {
-+            return map.entrySet();
-+        }
-+
-+
-+        protected Map.Entry<K, V> iteratorNext(Map.Entry<K, V> entry) {
-+            return entry;
-+        }
-+
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/FixedSizeMap.java
-@@ -0,0 +1,155 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.BoundedMap;
-+import org.apache.commons.collections15.collection.UnmodifiableCollection;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Map</code> to fix the size, preventing add/remove.
-+ * <p/>
-+ * Any action that would change the size of the map is disallowed.
-+ * The put method is allowed to change the value associated with an existing
-+ * key however.
-+ * <p/>
-+ * If trying to remove or clear the map, an UnsupportedOperationException is
-+ * thrown. If trying to put a new mapping into the map, an
-+ * IllegalArgumentException is thrown. This is because the put method can
-+ * succeed if the mapping's key already exists in the map, so the put method
-+ * is not always unsupported.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class FixedSizeMap <K,V> extends AbstractMapDecorator<K, V> implements Map<K, V>, BoundedMap<K, V>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 7450927208116179316L;
-+
-+    /**
-+     * Factory method to create a fixed size map.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> Map<K, V> decorate(Map<K, V> map) {
-+        return new FixedSizeMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    protected FixedSizeMap(Map<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map<K, V>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public V put(K key, V value) {
-+        if (map.containsKey(key) == false) {
-+            throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size");
-+        }
-+        return map.put(key, value);
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        for (Iterator it = mapToCopy.keySet().iterator(); it.hasNext();) {
-+            if (mapToCopy.containsKey(it.next()) == false) {
-+                throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size");
-+            }
-+        }
-+        map.putAll(mapToCopy);
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException("Map is fixed size");
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException("Map is fixed size");
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = map.entrySet();
-+        // unmodifiable set will still allow modification via Map.Entry objects
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = map.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Collection<V> values() {
-+        Collection<V> coll = map.values();
-+        return UnmodifiableCollection.decorate(coll);
-+    }
-+
-+    public boolean isFull() {
-+        return true;
-+    }
-+
-+    public int maxSize() {
-+        return size();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/FixedSizeSortedMap.java
-@@ -0,0 +1,167 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.BoundedMap;
-+import org.apache.commons.collections15.collection.UnmodifiableCollection;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * Decorates another <code>SortedMap</code> to fix the size blocking add/remove.
-+ * <p/>
-+ * Any action that would change the size of the map is disallowed.
-+ * The put method is allowed to change the value associated with an existing
-+ * key however.
-+ * <p/>
-+ * If trying to remove or clear the map, an UnsupportedOperationException is
-+ * thrown. If trying to put a new mapping into the map, an
-+ * IllegalArgumentException is thrown. This is because the put method can
-+ * succeed if the mapping's key already exists in the map, so the put method
-+ * is not always unsupported.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class FixedSizeSortedMap <K,V> extends AbstractSortedMapDecorator<K, V> implements SortedMap<K, V>, BoundedMap<K, V>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 3126019624511683653L;
-+
-+    /**
-+     * Factory method to create a fixed size sorted map.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> SortedMap<K, V> decorate(SortedMap<K, V> map) {
-+        return new FixedSizeSortedMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    protected FixedSizeSortedMap(SortedMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected SortedMap<K, V> getSortedMap() {
-+        return (SortedMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map<K, V>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public V put(K key, V value) {
-+        if (map.containsKey(key) == false) {
-+            throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size");
-+        }
-+        return map.put(key, value);
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        for (Iterator it = mapToCopy.keySet().iterator(); it.hasNext();) {
-+            if (mapToCopy.containsKey(it.next()) == false) {
-+                throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size");
-+            }
-+        }
-+        map.putAll(mapToCopy);
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException("Map is fixed size");
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException("Map is fixed size");
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = map.entrySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = map.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Collection<V> values() {
-+        Collection<V> coll = map.values();
-+        return UnmodifiableCollection.decorate(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        SortedMap<K, V> map = getSortedMap().subMap(fromKey, toKey);
-+        return new FixedSizeSortedMap<K, V>(map);
-+    }
-+
-+    public SortedMap<K, V> headMap(K toKey) {
-+        SortedMap<K, V> map = getSortedMap().headMap(toKey);
-+        return new FixedSizeSortedMap<K, V>(map);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        SortedMap<K, V> map = getSortedMap().tailMap(fromKey);
-+        return new FixedSizeSortedMap<K, V>(map);
-+    }
-+
-+    public boolean isFull() {
-+        return true;
-+    }
-+
-+    public int maxSize() {
-+        return size();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/Flat3Map.java
-@@ -0,0 +1,1151 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.IterableMap;
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.ResettableIterator;
-+import org.apache.commons.collections15.iterators.EmptyIterator;
-+import org.apache.commons.collections15.iterators.EmptyMapIterator;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * A <code>Map</code> implementation that stores data in simple fields until
-+ * the size is greater than 3.
-+ * <p/>
-+ * This map is designed for performance and can outstrip HashMap.
-+ * It also has good garbage collection characteristics.
-+ * <ul>
-+ * <li>Optimised for operation at size 3 or less.
-+ * <li>Still works well once size 3 exceeded.
-+ * <li>Gets at size 3 or less are about 0-10% faster than HashMap,
-+ * <li>Puts at size 3 or less are over 4 times faster than HashMap.
-+ * <li>Performance 5% slower than HashMap once size 3 exceeded once.
-+ * </ul>
-+ * The design uses two distinct modes of operation - flat and delegate.
-+ * While the map is size 3 or less, operations map straight onto fields using
-+ * switch statements. Once size 4 is reached, the map switches to delegate mode
-+ * and only switches back when cleared. In delegate mode, all operations are
-+ * forwarded straight to a HashMap resulting in the 5% performance loss.
-+ * <p/>
-+ * The performance gains on puts are due to not needing to create a Map Entry
-+ * object. This is a large saving not only in performance but in garbage collection.
-+ * <p/>
-+ * Whilst in flat mode this map is also easy for the garbage collector to dispatch.
-+ * This is because it contains no complex objects or arrays which slow the progress.
-+ * <p/>
-+ * Do not use <code>Flat3Map</code> if the size is likely to grow beyond 3.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class Flat3Map <K,V> implements IterableMap<K, V>, Serializable, Cloneable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -6701087419741928296L;
-+
-+    /**
-+     * The size of the map, used while in flat mode
-+     */
-+    private transient int size;
-+    /**
-+     * Hash, used while in flat mode
-+     */
-+    private transient int hash1;
-+    /**
-+     * Hash, used while in flat mode
-+     */
-+    private transient int hash2;
-+    /**
-+     * Hash, used while in flat mode
-+     */
-+    private transient int hash3;
-+    /**
-+     * Key, used while in flat mode
-+     */
-+    private transient K key1;
-+    /**
-+     * Key, used while in flat mode
-+     */
-+    private transient K key2;
-+    /**
-+     * Key, used while in flat mode
-+     */
-+    private transient K key3;
-+    /**
-+     * Value, used while in flat mode
-+     */
-+    private transient V value1;
-+    /**
-+     * Value, used while in flat mode
-+     */
-+    private transient V value2;
-+    /**
-+     * Value, used while in flat mode
-+     */
-+    private transient V value3;
-+    /**
-+     * Map, used while in delegate mode
-+     */
-+    private transient AbstractHashedMap<K, V> delegateMap;
-+
-+    /**
-+     * Constructor.
-+     */
-+    public Flat3Map() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException if the map is null
-+     */
-+    public Flat3Map(Map<K, V> map) {
-+        super();
-+        putAll(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the value mapped to the key specified.
-+     *
-+     * @param key the key
-+     * @return the mapped value, null if no match
-+     */
-+    public V get(Object key) {
-+        if (delegateMap != null) {
-+            return delegateMap.get(key);
-+        }
-+        if (key == null) {
-+            switch (size) {
-+                // drop through
-+                case 3:
-+                    if (key3 == null) return value3;
-+                case 2:
-+                    if (key2 == null) return value2;
-+                case 1:
-+                    if (key1 == null) return value1;
-+            }
-+        } else {
-+            if (size > 0) {
-+                int hashCode = key.hashCode();
-+                switch (size) {
-+                    // drop through
-+                    case 3:
-+                        if (hash3 == hashCode && key.equals(key3)) return value3;
-+                    case 2:
-+                        if (hash2 == hashCode && key.equals(key2)) return value2;
-+                    case 1:
-+                        if (hash1 == hashCode && key.equals(key1)) return value1;
-+                }
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets the size of the map.
-+     *
-+     * @return the size
-+     */
-+    public int size() {
-+        if (delegateMap != null) {
-+            return delegateMap.size();
-+        }
-+        return size;
-+    }
-+
-+    /**
-+     * Checks whether the map is currently empty.
-+     *
-+     * @return true if the map is currently size zero
-+     */
-+    public boolean isEmpty() {
-+        return (size() == 0);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks whether the map contains the specified key.
-+     *
-+     * @param key the key to search for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsKey(Object key) {
-+        if (delegateMap != null) {
-+            return delegateMap.containsKey(key);
-+        }
-+        if (key == null) {
-+            switch (size) {  // drop through
-+                case 3:
-+                    if (key3 == null) return true;
-+                case 2:
-+                    if (key2 == null) return true;
-+                case 1:
-+                    if (key1 == null) return true;
-+            }
-+        } else {
-+            if (size > 0) {
-+                int hashCode = key.hashCode();
-+                switch (size) {  // drop through
-+                    case 3:
-+                        if (hash3 == hashCode && key.equals(key3)) return true;
-+                    case 2:
-+                        if (hash2 == hashCode && key.equals(key2)) return true;
-+                    case 1:
-+                        if (hash1 == hashCode && key.equals(key1)) return true;
-+                }
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Checks whether the map contains the specified value.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsValue(Object value) {
-+        if (delegateMap != null) {
-+            return delegateMap.containsValue(value);
-+        }
-+        if (value == null) {  // drop through
-+            switch (size) {
-+                case 3:
-+                    if (value3 == null) return true;
-+                case 2:
-+                    if (value2 == null) return true;
-+                case 1:
-+                    if (value1 == null) return true;
-+            }
-+        } else {
-+            switch (size) {  // drop through
-+                case 3:
-+                    if (value.equals(value3)) return true;
-+                case 2:
-+                    if (value.equals(value2)) return true;
-+                case 1:
-+                    if (value.equals(value1)) return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Puts a key-value mapping into this map.
-+     *
-+     * @param key   the key to add
-+     * @param value the value to add
-+     * @return the value previously mapped to this key, null if none
-+     */
-+    public V put(K key, V value) {
-+        if (delegateMap != null) {
-+            return delegateMap.put(key, value);
-+        }
-+        // change existing mapping
-+        if (key == null) {
-+            switch (size) {  // drop through
-+                case 3:
-+                    if (key3 == null) {
-+                        V old = value3;
-+                        value3 = value;
-+                        return old;
-+                    }
-+                case 2:
-+                    if (key2 == null) {
-+                        V old = value2;
-+                        value2 = value;
-+                        return old;
-+                    }
-+                case 1:
-+                    if (key1 == null) {
-+                        V old = value1;
-+                        value1 = value;
-+                        return old;
-+                    }
-+            }
-+        } else {
-+            if (size > 0) {
-+                int hashCode = key.hashCode();
-+                switch (size) {  // drop through
-+                    case 3:
-+                        if (hash3 == hashCode && key.equals(key3)) {
-+                            V old = value3;
-+                            value3 = value;
-+                            return old;
-+                        }
-+                    case 2:
-+                        if (hash2 == hashCode && key.equals(key2)) {
-+                            V old = value2;
-+                            value2 = value;
-+                            return old;
-+                        }
-+                    case 1:
-+                        if (hash1 == hashCode && key.equals(key1)) {
-+                            V old = value1;
-+                            value1 = value;
-+                            return old;
-+                        }
-+                }
-+            }
-+        }
-+        
-+        // add new mapping
-+        switch (size) {
-+            default:
-+                convertToMap();
-+                delegateMap.put(key, value);
-+                return null;
-+            case 2:
-+                hash3 = (key == null ? 0 : key.hashCode());
-+                key3 = key;
-+                value3 = value;
-+                break;
-+            case 1:
-+                hash2 = (key == null ? 0 : key.hashCode());
-+                key2 = key;
-+                value2 = value;
-+                break;
-+            case 0:
-+                hash1 = (key == null ? 0 : key.hashCode());
-+                key1 = key;
-+                value1 = value;
-+                break;
-+        }
-+        size++;
-+        return null;
-+    }
-+
-+    /**
-+     * Puts all the values from the specified map into this map.
-+     *
-+     * @param map the map to add
-+     * @throws NullPointerException if the map is null
-+     */
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        int size = map.size();
-+        if (size == 0) {
-+            return;
-+        }
-+        if (delegateMap != null) {
-+            delegateMap.putAll(map);
-+            return;
-+        }
-+        if (size < 4) {
-+            for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-+                Map.Entry<? extends K, ? extends V> entry = (Map.Entry<? extends K, ? extends V>) it.next();
-+                put(entry.getKey(), entry.getValue());
-+            }
-+        } else {
-+            convertToMap();
-+            delegateMap.putAll(map);
-+        }
-+    }
-+
-+    /**
-+     * Converts the flat map data to a map.
-+     */
-+    private void convertToMap() {
-+        delegateMap = createDelegateMap();
-+        switch (size) {  // drop through
-+            case 3:
-+                delegateMap.put(key3, value3);
-+            case 2:
-+                delegateMap.put(key2, value2);
-+            case 1:
-+                delegateMap.put(key1, value1);
-+        }
-+
-+        size = 0;
-+        hash1 = hash2 = hash3 = 0;
-+        key1 = key2 = key3 = null;
-+        value1 = value2 = value3 = null;
-+    }
-+
-+    /**
-+     * Create an instance of the map used for storage when in delegation mode.
-+     * <p/>
-+     * This can be overridden by subclasses to provide a different map implementation.
-+     * Not every AbstractHashedMap is suitable, identity and reference based maps
-+     * would be poor choices.
-+     *
-+     * @return a new AbstractHashedMap or subclass
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractHashedMap<K, V> createDelegateMap() {
-+        return new HashedMap<K, V>();
-+    }
-+
-+    /**
-+     * Removes the specified mapping from this map.
-+     *
-+     * @param key the mapping to remove
-+     * @return the value mapped to the removed key, null if key not in map
-+     */
-+    public V remove(Object key) {
-+        if (delegateMap != null) {
-+            return delegateMap.remove(key);
-+        }
-+        if (size == 0) {
-+            return null;
-+        }
-+        if (key == null) {
-+            switch (size) {  // drop through
-+                case 3:
-+                    if (key3 == null) {
-+                        V old = value3;
-+                        hash3 = 0;
-+                        key3 = null;
-+                        value3 = null;
-+                        size = 2;
-+                        return old;
-+                    }
-+                    if (key2 == null) {
-+                        V old = value3;
-+                        hash2 = hash3;
-+                        key2 = key3;
-+                        value2 = value3;
-+                        hash3 = 0;
-+                        key3 = null;
-+                        value3 = null;
-+                        size = 2;
-+                        return old;
-+                    }
-+                    if (key1 == null) {
-+                        V old = value3;
-+                        hash1 = hash3;
-+                        key1 = key3;
-+                        value1 = value3;
-+                        hash3 = 0;
-+                        key3 = null;
-+                        value3 = null;
-+                        size = 2;
-+                        return old;
-+                    }
-+                    return null;
-+                case 2:
-+                    if (key2 == null) {
-+                        V old = value2;
-+                        hash2 = 0;
-+                        key2 = null;
-+                        value2 = null;
-+                        size = 1;
-+                        return old;
-+                    }
-+                    if (key1 == null) {
-+                        V old = value2;
-+                        hash1 = hash2;
-+                        key1 = key2;
-+                        value1 = value2;
-+                        hash2 = 0;
-+                        key2 = null;
-+                        value2 = null;
-+                        size = 1;
-+                        return old;
-+                    }
-+                    return null;
-+                case 1:
-+                    if (key1 == null) {
-+                        V old = value1;
-+                        hash1 = 0;
-+                        key1 = null;
-+                        value1 = null;
-+                        size = 0;
-+                        return old;
-+                    }
-+            }
-+        } else {
-+            if (size > 0) {
-+                int hashCode = key.hashCode();
-+                switch (size) {  // drop through
-+                    case 3:
-+                        if (hash3 == hashCode && key.equals(key3)) {
-+                            V old = value3;
-+                            hash3 = 0;
-+                            key3 = null;
-+                            value3 = null;
-+                            size = 2;
-+                            return old;
-+                        }
-+                        if (hash2 == hashCode && key.equals(key2)) {
-+                            V old = value3;
-+                            hash2 = hash3;
-+                            key2 = key3;
-+                            value2 = value3;
-+                            hash3 = 0;
-+                            key3 = null;
-+                            value3 = null;
-+                            size = 2;
-+                            return old;
-+                        }
-+                        if (hash1 == hashCode && key.equals(key1)) {
-+                            V old = value3;
-+                            hash1 = hash3;
-+                            key1 = key3;
-+                            value1 = value3;
-+                            hash3 = 0;
-+                            key3 = null;
-+                            value3 = null;
-+                            size = 2;
-+                            return old;
-+                        }
-+                        return null;
-+                    case 2:
-+                        if (hash2 == hashCode && key.equals(key2)) {
-+                            V old = value2;
-+                            hash2 = 0;
-+                            key2 = null;
-+                            value2 = null;
-+                            size = 1;
-+                            return old;
-+                        }
-+                        if (hash1 == hashCode && key.equals(key1)) {
-+                            V old = value2;
-+                            hash1 = hash2;
-+                            key1 = key2;
-+                            value1 = value2;
-+                            hash2 = 0;
-+                            key2 = null;
-+                            value2 = null;
-+                            size = 1;
-+                            return old;
-+                        }
-+                        return null;
-+                    case 1:
-+                        if (hash1 == hashCode && key.equals(key1)) {
-+                            V old = value1;
-+                            hash1 = 0;
-+                            key1 = null;
-+                            value1 = null;
-+                            size = 0;
-+                            return old;
-+                        }
-+                }
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Clears the map, resetting the size to zero and nullifying references
-+     * to avoid garbage collection issues.
-+     */
-+    public void clear() {
-+        if (delegateMap != null) {
-+            delegateMap.clear();  // should aid gc
-+            delegateMap = null;  // switch back to flat mode
-+        } else {
-+            size = 0;
-+            hash1 = hash2 = hash3 = 0;
-+            key1 = key2 = key3 = null;
-+            value1 = value2 = value3 = null;
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an iterator over the map.
-+     * Changes made to the iterator affect this map.
-+     * <p/>
-+     * A MapIterator returns the keys in the map. It also provides convenient
-+     * methods to get the key and value, and set the value.
-+     * It avoids the need to create an entrySet/keySet/values object.
-+     * It also avoids creating the Map Entry object.
-+     *
-+     * @return the map iterator
-+     */
-+    public MapIterator<K, V> mapIterator() {
-+        if (delegateMap != null) {
-+            return delegateMap.mapIterator();
-+        }
-+        if (size == 0) {
-+            return EmptyMapIterator.INSTANCE;
-+        }
-+        return new FlatMapIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * FlatMapIterator
-+     */
-+    static class FlatMapIterator <K,V> implements MapIterator<K, V>, ResettableIterator<K> {
-+        private final Flat3Map<K, V> parent;
-+        private int nextIndex = 0;
-+        private boolean canRemove = false;
-+
-+        FlatMapIterator(Flat3Map<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public boolean hasNext() {
-+            return (nextIndex < parent.size);
-+        }
-+
-+        public K next() {
-+            if (hasNext() == false) {
-+                throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
-+            }
-+            canRemove = true;
-+            nextIndex++;
-+            return getKey();
-+        }
-+
-+        public void remove() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
-+            }
-+            parent.remove(getKey());
-+            nextIndex--;
-+            canRemove = false;
-+        }
-+
-+        public K getKey() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
-+            }
-+            switch (nextIndex) {
-+                case 3:
-+                    return parent.key3;
-+                case 2:
-+                    return parent.key2;
-+                case 1:
-+                    return parent.key1;
-+            }
-+            throw new IllegalStateException("Invalid map index");
-+        }
-+
-+        public V getValue() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
-+            }
-+            switch (nextIndex) {
-+                case 3:
-+                    return parent.value3;
-+                case 2:
-+                    return parent.value2;
-+                case 1:
-+                    return parent.value1;
-+            }
-+            throw new IllegalStateException("Invalid map index");
-+        }
-+
-+        public V setValue(V value) {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
-+            }
-+            V old = getValue();
-+            switch (nextIndex) {
-+                case 3:
-+                    parent.value3 = value;
-+                case 2:
-+                    parent.value2 = value;
-+                case 1:
-+                    parent.value1 = value;
-+            }
-+            return old;
-+        }
-+
-+        public void reset() {
-+            nextIndex = 0;
-+            canRemove = false;
-+        }
-+
-+        public String toString() {
-+            if (canRemove) {
-+                return "Iterator[" + getKey() + "=" + getValue() + "]";
-+            } else {
-+                return "Iterator[]";
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Gets the entrySet view of the map.
-+     * Changes made to the view affect this map.
-+     * The Map Entry is not an independent object and changes as the
-+     * iterator progresses.
-+     * To simply iterate through the entries, use {@link #mapIterator()}.
-+     *
-+     * @return the entrySet view
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        if (delegateMap != null) {
-+            return delegateMap.entrySet();
-+        }
-+        return new EntrySet<K, V>(this);
-+    }
-+
-+    /**
-+     * EntrySet
-+     */
-+    static class EntrySet <K,V> extends AbstractSet<Map.Entry<K, V>> {
-+        private final Flat3Map<K, V> parent;
-+
-+        EntrySet(Flat3Map<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return parent.size();
-+        }
-+
-+        public void clear() {
-+            parent.clear();
-+        }
-+
-+        public boolean remove(Object obj) {
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry entry = (Map.Entry) obj;
-+            Object key = entry.getKey();
-+            boolean result = parent.containsKey(key);
-+            parent.remove(key);
-+            return result;
-+        }
-+
-+        public Iterator<Map.Entry<K, V>> iterator() {
-+            if (parent.delegateMap != null) {
-+                return parent.delegateMap.entrySet().iterator();
-+            }
-+            if (parent.size() == 0) {
-+                return EmptyIterator.INSTANCE;
-+            }
-+            return new EntrySetIterator<K, V>(parent);
-+        }
-+    }
-+
-+    static class EntrySetIterator <K,V> extends IteratorBase<K, V> implements Iterator<Map.Entry<K, V>> {
-+
-+        public EntrySetIterator(Flat3Map<K, V> flat3Map) {
-+            super(flat3Map);
-+        }
-+
-+        public Entry<K, V> next() {
-+            return superNext();  //To change body of implemented methods use File | Settings | File Templates.
-+        }
-+
-+    }
-+
-+    /**
-+     * EntrySetIterator and MapEntry
-+     */
-+    static class IteratorBase <K,V> implements Map.Entry<K, V> {
-+        private final Flat3Map<K, V> parent;
-+        private int nextIndex = 0;
-+        private boolean canRemove = false;
-+
-+        IteratorBase(Flat3Map<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public boolean hasNext() {
-+            return (nextIndex < parent.size);
-+        }
-+
-+        public void remove() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
-+            }
-+            parent.remove(getKey());
-+            nextIndex--;
-+            canRemove = false;
-+        }
-+
-+        public K getKey() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
-+            }
-+            switch (nextIndex) {
-+                case 3:
-+                    return parent.key3;
-+                case 2:
-+                    return parent.key2;
-+                case 1:
-+                    return parent.key1;
-+            }
-+            throw new IllegalStateException("Invalid map index");
-+        }
-+
-+        public Map.Entry<K, V> superNext() {
-+            if (hasNext() == false) {
-+                throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
-+            }
-+            canRemove = true;
-+            nextIndex++;
-+            return this;
-+        }
-+
-+        public V getValue() {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
-+            }
-+            switch (nextIndex) {
-+                case 3:
-+                    return parent.value3;
-+                case 2:
-+                    return parent.value2;
-+                case 1:
-+                    return parent.value1;
-+            }
-+            throw new IllegalStateException("Invalid map index");
-+        }
-+
-+        public V setValue(V value) {
-+            if (canRemove == false) {
-+                throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
-+            }
-+            V old = getValue();
-+            switch (nextIndex) {
-+                case 3:
-+                    parent.value3 = value;
-+                case 2:
-+                    parent.value2 = value;
-+                case 1:
-+                    parent.value1 = value;
-+            }
-+            return old;
-+        }
-+
-+        public boolean equals(Object obj) {
-+            if (canRemove == false) {
-+                return false;
-+            }
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry other = (Map.Entry) obj;
-+            Object key = getKey();
-+            Object value = getValue();
-+            return (key == null ? other.getKey() == null : key.equals(other.getKey())) && (value == null ? other.getValue() == null : value.equals(other.getValue()));
-+        }
-+
-+        public int hashCode() {
-+            if (canRemove == false) {
-+                return 0;
-+            }
-+            Object key = getKey();
-+            Object value = getValue();
-+            return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
-+        }
-+
-+        public String toString() {
-+            if (canRemove) {
-+                return getKey() + "=" + getValue();
-+            } else {
-+                return "";
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Gets the keySet view of the map.
-+     * Changes made to the view affect this map.
-+     * To simply iterate through the keys, use {@link #mapIterator()}.
-+     *
-+     * @return the keySet view
-+     */
-+    public Set keySet() {
-+        if (delegateMap != null) {
-+            return delegateMap.keySet();
-+        }
-+        return new KeySet(this);
-+    }
-+
-+    /**
-+     * KeySet
-+     */
-+    static class KeySet <K,V> extends AbstractSet<K> {
-+        private final Flat3Map<K, V> parent;
-+
-+        KeySet(Flat3Map<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return parent.size();
-+        }
-+
-+        public void clear() {
-+            parent.clear();
-+        }
-+
-+        public boolean contains(Object key) {
-+            return parent.containsKey(key);
-+        }
-+
-+        public boolean remove(Object key) {
-+            boolean result = parent.containsKey(key);
-+            parent.remove(key);
-+            return result;
-+        }
-+
-+        public Iterator<K> iterator() {
-+            if (parent.delegateMap != null) {
-+                return parent.delegateMap.keySet().iterator();
-+            }
-+            if (parent.size() == 0) {
-+                return EmptyIterator.INSTANCE;
-+            }
-+            return new KeySetIterator<K, V>(parent);
-+        }
-+    }
-+
-+    /**
-+     * KeySetIterator
-+     */
-+    static class KeySetIterator <K,V> extends IteratorBase<K, V> implements Iterator<K> {
-+
-+        KeySetIterator(Flat3Map<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public K next() {
-+            superNext();
-+            return getKey();
-+        }
-+    }
-+
-+    /**
-+     * Gets the values view of the map.
-+     * Changes made to the view affect this map.
-+     * To simply iterate through the values, use {@link #mapIterator()}.
-+     *
-+     * @return the values view
-+     */
-+    public Collection<V> values() {
-+        if (delegateMap != null) {
-+            return delegateMap.values();
-+        }
-+        return new Values<K, V>(this);
-+    }
-+
-+    /**
-+     * Values
-+     */
-+    static class Values <K,V> extends AbstractCollection<V> {
-+        private final Flat3Map<K, V> parent;
-+
-+        Values(Flat3Map<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return parent.size();
-+        }
-+
-+        public void clear() {
-+            parent.clear();
-+        }
-+
-+        public boolean contains(Object value) {
-+            return parent.containsValue(value);
-+        }
-+
-+        public Iterator<V> iterator() {
-+            if (parent.delegateMap != null) {
-+                return parent.delegateMap.values().iterator();
-+            }
-+            if (parent.size() == 0) {
-+                return EmptyIterator.INSTANCE;
-+            }
-+            return new ValuesIterator<K, V>(parent);
-+        }
-+    }
-+
-+    /**
-+     * ValuesIterator
-+     */
-+    static class ValuesIterator <K,V> extends IteratorBase<K, V> implements Iterator<V> {
-+
-+        ValuesIterator(Flat3Map<K, V> parent) {
-+            super(parent);
-+        }
-+
-+        public V next() {
-+            superNext();
-+            return getValue();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeInt(size());
-+        for (MapIterator it = mapIterator(); it.hasNext();) {
-+            out.writeObject(it.next());  // key
-+            out.writeObject(it.getValue());  // value
-+        }
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        int count = in.readInt();
-+        if (count > 3) {
-+            delegateMap = createDelegateMap();
-+        }
-+        for (int i = count; i > 0; i--) {
-+            put((K) in.readObject(), (V) in.readObject());
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     *
-+     * @return a shallow clone
-+     * @since Commons Collections 3.1
-+     */
-+    public Object clone() {
-+        try {
-+            Flat3Map cloned = (Flat3Map) super.clone();
-+            if (cloned.delegateMap != null) {
-+                cloned.delegateMap = (HashedMap) cloned.delegateMap.clone();
-+            }
-+            return cloned;
-+        } catch (CloneNotSupportedException ex) {
-+            throw new InternalError();
-+        }
-+    }
-+
-+    /**
-+     * Compares this map with another.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (delegateMap != null) {
-+            return delegateMap.equals(obj);
-+        }
-+        if (obj instanceof Map == false) {
-+            return false;
-+        }
-+        Map other = (Map) obj;
-+        if (size != other.size()) {
-+            return false;
-+        }
-+        if (size > 0) {
-+            Object otherValue = null;
-+            switch (size) {  // drop through
-+                case 3:
-+                    if (other.containsKey(key3) == false) {
-+                        otherValue = other.get(key3);
-+                        if (value3 == null ? otherValue != null : !value3.equals(otherValue)) {
-+                            return false;
-+                        }
-+                    }
-+                case 2:
-+                    if (other.containsKey(key2) == false) {
-+                        otherValue = other.get(key2);
-+                        if (value2 == null ? otherValue != null : !value2.equals(otherValue)) {
-+                            return false;
-+                        }
-+                    }
-+                case 1:
-+                    if (other.containsKey(key1) == false) {
-+                        otherValue = other.get(key1);
-+                        if (value1 == null ? otherValue != null : !value1.equals(otherValue)) {
-+                            return false;
-+                        }
-+                    }
-+            }
-+        }
-+        return true;
-+    }
-+
-+    /**
-+     * Gets the standard Map hashCode.
-+     *
-+     * @return the hash code defined in the Map interface
-+     */
-+    public int hashCode() {
-+        if (delegateMap != null) {
-+            return delegateMap.hashCode();
-+        }
-+        int total = 0;
-+        switch (size) {  // drop through
-+            case 3:
-+                total += (hash3 ^ (value3 == null ? 0 : value3.hashCode()));
-+            case 2:
-+                total += (hash2 ^ (value2 == null ? 0 : value2.hashCode()));
-+            case 1:
-+                total += (hash1 ^ (value1 == null ? 0 : value1.hashCode()));
-+        }
-+        return total;
-+    }
-+
-+    /**
-+     * Gets the map as a String.
-+     *
-+     * @return a string version of the map
-+     */
-+    public String toString() {
-+        if (delegateMap != null) {
-+            return delegateMap.toString();
-+        }
-+        if (size == 0) {
-+            return "{}";
-+        }
-+        StringBuffer buf = new StringBuffer(128);
-+        buf.append('{');
-+        switch (size) {  // drop through
-+            case 3:
-+                buf.append(key3);
-+                buf.append('=');
-+                buf.append(value3);
-+                buf.append(',');
-+            case 2:
-+                buf.append(key2);
-+                buf.append('=');
-+                buf.append(value2);
-+                buf.append(',');
-+            case 1:
-+                buf.append(key1);
-+                buf.append('=');
-+                buf.append(value1);
-+        }
-+        buf.append('}');
-+        return buf.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/HashedMap.java
-@@ -0,0 +1,111 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Map;
-+
-+/**
-+ * A <code>Map</code> implementation that is a general purpose alternative
-+ * to <code>HashMap</code>.
-+ * <p/>
-+ * This implementation improves on the JDK1.4 HashMap by adding the
-+ * {@link org.apache.commons.collections15.MapIterator MapIterator}
-+ * functionality and many methods for subclassing.
-+ * <p/>
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class HashedMap <K,V> extends AbstractHashedMap<K, V> implements Serializable, Cloneable {
-+
-+    /**
-+     * Serialisation version
-+     */
-+    private static final long serialVersionUID = -1788199231038721040L;
-+
-+    /**
-+     * Constructs a new empty map with default size and load factor.
-+     */
-+    public HashedMap() {
-+        super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_THRESHOLD);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     */
-+    public HashedMap(int initialCapacity) {
-+        super(initialCapacity);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @param loadFactor      the load factor
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     * @throws IllegalArgumentException if the load factor is less than zero
-+     */
-+    public HashedMap(int initialCapacity, float loadFactor) {
-+        super(initialCapacity, loadFactor);
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException if the map is null
-+     */
-+    public HashedMap(Map<? extends K, ? extends V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     *
-+     * @return a shallow clone
-+     */
-+    public Object clone() {
-+        return super.clone();
-+    }
-+
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/IdentityMap.java
-@@ -0,0 +1,186 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Map;
-+
-+/**
-+ * A <code>Map</code> implementation that matches keys and values based
-+ * on <code>==</code> not <code>equals()</code>.
-+ * <p/>
-+ * This map will violate the detail of various Map and map view contracts.
-+ * As a general rule, don't compare this map to other maps.
-+ *
-+ * @author java util HashMap
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class IdentityMap <K,V> extends AbstractHashedMap<K, V> implements Serializable, Cloneable {
-+
-+    /**
-+     * Serialisation version
-+     */
-+    private static final long serialVersionUID = 2028493495224302329L;
-+
-+    /**
-+     * Constructs a new empty map with default size and load factor.
-+     */
-+    public IdentityMap() {
-+        super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_THRESHOLD);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     */
-+    public IdentityMap(int initialCapacity) {
-+        super(initialCapacity);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @param loadFactor      the load factor
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     * @throws IllegalArgumentException if the load factor is less than zero
-+     */
-+    public IdentityMap(int initialCapacity, float loadFactor) {
-+        super(initialCapacity, loadFactor);
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException if the map is null
-+     */
-+    public IdentityMap(Map<? extends K, ? extends V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the hash code for the key specified.
-+     * This implementation uses the identity hash code.
-+     *
-+     * @param key the key to get a hash code for
-+     * @return the hash code
-+     */
-+    protected int hash(Object key) {
-+        return System.identityHashCode(key);
-+    }
-+
-+    /**
-+     * Compares two keys for equals.
-+     * This implementation uses <code>==</code>.
-+     *
-+     * @param key1 the first key to compare
-+     * @param key2 the second key to compare
-+     * @return true if equal by identity
-+     */
-+    protected boolean isEqualKey(Object key1, Object key2) {
-+        return (key1 == key2);
-+    }
-+
-+    /**
-+     * Compares two values for equals.
-+     * This implementation uses <code>==</code>.
-+     *
-+     * @param value1 the first value to compare
-+     * @param value2 the second value to compare
-+     * @return true if equal by identity
-+     */
-+    protected boolean isEqualValue(Object value1, Object value2) {
-+        return (value1 == value2);
-+    }
-+
-+    /**
-+     * Creates an entry to store the data.
-+     * This implementation creates an IdentityEntry instance.
-+     *
-+     * @param next     the next entry in sequence
-+     * @param hashCode the hash code to use
-+     * @param key      the key to store
-+     * @param value    the value to store
-+     * @return the newly created entry
-+     */
-+    protected HashEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
-+        return new IdentityEntry<K, V>(next, hashCode, key, value);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * HashEntry
-+     */
-+    protected static class IdentityEntry <K,V> extends HashEntry<K, V> {
-+
-+        protected IdentityEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
-+            super(next, hashCode, key, value);
-+        }
-+
-+        public boolean equals(Object obj) {
-+            if (obj == this) {
-+                return true;
-+            }
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry other = (Map.Entry) obj;
-+            return (getKey() == other.getKey()) && (getValue() == other.getValue());
-+        }
-+
-+        public int hashCode() {
-+            return System.identityHashCode(getKey()) ^ System.identityHashCode(getValue());
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     *
-+     * @return a shallow clone
-+     */
-+    public Object clone() {
-+        return super.clone();
-+    }
-+
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/LRUMap.java
-@@ -0,0 +1,398 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.BoundedMap;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Map;
-+
-+/**
-+ * A <code>Map</code> implementation with a fixed maximum size which removes
-+ * the least recently used entry if an entry is added when full.
-+ * <p/>
-+ * The least recently used algorithm works on the get and put operations only.
-+ * Iteration of any kind, including setting the value by iteration, does not
-+ * change the order. Queries such as containsKey and containsValue or access
-+ * via views also do not change the order.
-+ * <p/>
-+ * The map implements <code>OrderedMap</code> and entries may be queried using
-+ * the bidirectional <code>OrderedMapIterator</code>. The order returned is
-+ * least recently used to most recently used. Iterators from map views can
-+ * also be cast to <code>OrderedIterator</code> if required.
-+ * <p/>
-+ * All the available iterators can be reset back to the start by casting to
-+ * <code>ResettableIterator</code> and calling <code>reset()</code>.
-+ *
-+ * @author James Strachan
-+ * @author Morgan Delagrange
-+ * @author Stephen Colebourne
-+ * @author Mike Pettypiece
-+ * @author Matt Hall, John Watkinson, Mario Ivankovits
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0 (previously in main package v1.0)
-+ */
-+public class LRUMap <K,V> extends AbstractLinkedMap<K, V> implements BoundedMap<K, V>, Serializable, Cloneable {
-+
-+    /**
-+     * Serialisation version
-+     */
-+    static final long serialVersionUID = -612114643488955218L;
-+    /**
-+     * Default maximum size
-+     */
-+    protected static final int DEFAULT_MAX_SIZE = 100;
-+
-+    /**
-+     * Maximum size
-+     */
-+    private transient int maxSize;
-+    /**
-+     * Scan behaviour
-+     */
-+    private boolean scanUntilRemovable;
-+
-+    /**
-+     * Constructs a new empty map with a maximum size of 100.
-+     */
-+    public LRUMap() {
-+        this(DEFAULT_MAX_SIZE, DEFAULT_LOAD_FACTOR, false);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified maximum size.
-+     *
-+     * @param maxSize the maximum size of the map
-+     * @throws IllegalArgumentException if the maximum size is less than one
-+     */
-+    public LRUMap(int maxSize) {
-+        this(maxSize, DEFAULT_LOAD_FACTOR);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified maximum size.
-+     *
-+     * @param maxSize            the maximum size of the map
-+     * @param scanUntilRemovable scan until a removeable entry is found, default false
-+     * @throws IllegalArgumentException if the maximum size is less than one
-+     * @since Commons Collections 3.1
-+     */
-+    public LRUMap(int maxSize, boolean scanUntilRemovable) {
-+        this(maxSize, DEFAULT_LOAD_FACTOR, scanUntilRemovable);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param maxSize    the maximum size of the map, -1 for no limit,
-+     * @param loadFactor the load factor
-+     * @throws IllegalArgumentException if the maximum size is less than one
-+     * @throws IllegalArgumentException if the load factor is less than zero
-+     */
-+    public LRUMap(int maxSize, float loadFactor) {
-+        this(maxSize, loadFactor, false);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param maxSize            the maximum size of the map, -1 for no limit,
-+     * @param loadFactor         the load factor
-+     * @param scanUntilRemovable scan until a removeable entry is found, default false
-+     * @throws IllegalArgumentException if the maximum size is less than one
-+     * @throws IllegalArgumentException if the load factor is less than zero
-+     * @since Commons Collections 3.1
-+     */
-+    public LRUMap(int maxSize, float loadFactor, boolean scanUntilRemovable) {
-+        super((maxSize < 1 ? DEFAULT_CAPACITY : maxSize), loadFactor);
-+        if (maxSize < 1) {
-+            throw new IllegalArgumentException("LRUMap max size must be greater than 0");
-+        }
-+        this.maxSize = maxSize;
-+        this.scanUntilRemovable = scanUntilRemovable;
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     * <p/>
-+     * The maximum size is set from the map's size.
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException     if the map is null
-+     * @throws IllegalArgumentException if the map is empty
-+     */
-+    public LRUMap(Map<? extends K, ? extends V> map) {
-+        this(map, false);
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     * <p/>
-+     * The maximum size is set from the map's size.
-+     *
-+     * @param map                the map to copy
-+     * @param scanUntilRemovable scan until a removeable entry is found, default false
-+     * @throws NullPointerException     if the map is null
-+     * @throws IllegalArgumentException if the map is empty
-+     * @since Commons Collections 3.1
-+     */
-+    public LRUMap(Map<? extends K, ? extends V> map, boolean scanUntilRemovable) {
-+        this(map.size(), DEFAULT_LOAD_FACTOR, scanUntilRemovable);
-+        putAll(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the value mapped to the key specified.
-+     * <p/>
-+     * This operation changes the position of the key in the map to the
-+     * most recently used position (first).
-+     *
-+     * @param key the key
-+     * @return the mapped value, null if no match
-+     */
-+    public V get(Object key) {
-+        LinkEntry<K, V> entry = (LinkEntry<K, V>) getEntry(key);
-+        if (entry == null) {
-+            return null;
-+        }
-+        moveToMRU(entry);
-+        return entry.getValue();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Moves an entry to the MRU position at the end of the list.
-+     * <p/>
-+     * This implementation moves the updated entry to the end of the list.
-+     *
-+     * @param entry the entry to update
-+     */
-+    protected void moveToMRU(LinkEntry<K, V> entry) {
-+        if (entry.after != header) {
-+            modCount++;
-+            // remove
-+            entry.before.after = entry.after;
-+            entry.after.before = entry.before;
-+            // add first
-+            entry.after = header;
-+            entry.before = header.before;
-+            header.before.after = entry;
-+            header.before = entry;
-+        }
-+    }
-+
-+    /**
-+     * Updates an existing key-value mapping.
-+     * <p/>
-+     * This implementation moves the updated entry to the top of the list
-+     * using {@link #moveToMRU(org.apache.commons.collections15.map.AbstractLinkedMap.LinkEntry)}.
-+     *
-+     * @param entry    the entry to update
-+     * @param newValue the new value to store
-+     */
-+    protected void updateEntry(HashEntry<K, V> entry, V newValue) {
-+        moveToMRU((LinkEntry<K, V>) entry);  // handles modCount
-+        entry.setValue(newValue);
-+    }
-+
-+    /**
-+     * Adds a new key-value mapping into this map.
-+     * <p/>
-+     * This implementation checks the LRU size and determines whether to
-+     * discard an entry or not using {@link #removeLRU(org.apache.commons.collections15.map.AbstractLinkedMap.LinkEntry)}.
-+     * <p/>
-+     * From Commons Collections 3.1 this method uses {@link #isFull()} rather
-+     * than accessing <code>size</code> and <code>maxSize</code> directly.
-+     * It also handles the scanUntilRemovable functionality.
-+     *
-+     * @param hashIndex the index into the data array to store at
-+     * @param hashCode  the hash code of the key to add
-+     * @param key       the key to add
-+     * @param value     the value to add
-+     */
-+    protected void addMapping(int hashIndex, int hashCode, K key, V value) {
-+        if (isFull()) {
-+            LinkEntry reuse = header.after;
-+            boolean removeLRUEntry = false;
-+            if (scanUntilRemovable) {
-+                while (reuse != header) {
-+                    if (removeLRU(reuse)) {
-+                        removeLRUEntry = true;
-+                        break;
-+                    }
-+                    reuse = reuse.after;
-+                }
-+            } else {
-+                removeLRUEntry = removeLRU(reuse);
-+            }
-+
-+            if (removeLRUEntry) {
-+                reuseMapping(reuse, hashIndex, hashCode, key, value);
-+            } else {
-+                super.addMapping(hashIndex, hashCode, key, value);
-+            }
-+        } else {
-+            super.addMapping(hashIndex, hashCode, key, value);
-+        }
-+    }
-+
-+    /**
-+     * Reuses an entry by removing it and moving it to a new place in the map.
-+     * <p/>
-+     * This method uses {@link #removeEntry}, {@link #reuseEntry} and {@link #addEntry}.
-+     *
-+     * @param entry     the entry to reuse
-+     * @param hashIndex the index into the data array to store at
-+     * @param hashCode  the hash code of the key to add
-+     * @param key       the key to add
-+     * @param value     the value to add
-+     */
-+    protected void reuseMapping(LinkEntry<K, V> entry, int hashIndex, int hashCode, K key, V value) {
-+        // find the entry before the entry specified in the hash table
-+        // remember that the parameters (except the first) refer to the new entry,
-+        // not the old one
-+        int removeIndex = hashIndex(entry.hashCode, data.length);
-+        HashEntry<K, V> loop = data[removeIndex];
-+        HashEntry<K, V> previous = null;
-+        while (loop != entry) {
-+            previous = loop;
-+            loop = loop.next;
-+        }
-+        
-+        // reuse the entry
-+        modCount++;
-+        removeEntry(entry, removeIndex, previous);
-+        reuseEntry(entry, hashIndex, hashCode, key, value);
-+        addEntry(entry, hashIndex);
-+    }
-+
-+    /**
-+     * Subclass method to control removal of the least recently used entry from the map.
-+     * <p/>
-+     * This method exists for subclasses to override. A subclass may wish to
-+     * provide cleanup of resources when an entry is removed. For example:
-+     * <pre>
-+     * protected boolean removeLRU(LinkEntry entry) {
-+     *   releaseResources(entry.getValue());  // release resources held by entry
-+     *   return true;  // actually delete entry
-+     * }
-+     * </pre>
-+     * <p/>
-+     * Alternatively, a subclass may choose to not remove the entry or selectively
-+     * keep certain LRU entries. For example:
-+     * <pre>
-+     * protected boolean removeLRU(LinkEntry entry) {
-+     *   if (entry.getKey().toString().startsWith("System.")) {
-+     *     return false;  // entry not removed from LRUMap
-+     *   } else {
-+     *     return true;  // actually delete entry
-+     *   }
-+     * }
-+     * </pre>
-+     * The effect of returning false is dependent on the scanUntilRemovable flag.
-+     * If the flag is true, the next LRU entry will be passed to this method and so on
-+     * until one returns false and is removed, or every entry in the map has been passed.
-+     * If the scanUntilRemovable flag is false, the map will exceed the maximum size.
-+     * <p/>
-+     * NOTE: Commons Collections 3.0 passed the wrong entry to this method.
-+     * This is fixed in version 3.1 onwards.
-+     *
-+     * @param entry the entry to be removed
-+     */
-+    protected boolean removeLRU(LinkEntry<K, V> entry) {
-+        return true;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns true if this map is full and no new mappings can be added.
-+     *
-+     * @return <code>true</code> if the map is full
-+     */
-+    public boolean isFull() {
-+        return (size >= maxSize);
-+    }
-+
-+    /**
-+     * Gets the maximum size of the map (the bound).
-+     *
-+     * @return the maximum number of elements the map can hold
-+     */
-+    public int maxSize() {
-+        return maxSize;
-+    }
-+
-+    /**
-+     * Whether this LRUMap will scan until a removable entry is found when the
-+     * map is full.
-+     *
-+     * @return true if this map scans
-+     * @since Commons Collections 3.1
-+     */
-+    public boolean isScanUntilRemovable() {
-+        return scanUntilRemovable;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     *
-+     * @return a shallow clone
-+     */
-+    public Object clone() {
-+        return super.clone();
-+    }
-+
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+    /**
-+     * Writes the data necessary for <code>put()</code> to work in deserialization.
-+     */
-+    protected void doWriteObject(ObjectOutputStream out) throws IOException {
-+        out.writeInt(maxSize);
-+        super.doWriteObject(out);
-+    }
-+
-+    /**
-+     * Reads the data necessary for <code>put()</code> to work in the superclass.
-+     */
-+    protected void doReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        maxSize = in.readInt();
-+        super.doReadObject(in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/LazyMap.java
-@@ -0,0 +1,167 @@
-+// GenericsNote: Converted -- Using a Transformer instead of a Factory is no longer allowed.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Map;
-+
-+import org.apache.commons.collections15.Factory;
-+import org.apache.commons.collections15.Transformer;
-+import org.apache.commons.collections15.functors.FactoryTransformer;
-+
-+/**
-+ * Decorates another <code>Map</code> to create objects in the map on demand.
-+ * <p/>
-+ * When the {@link #get(Object)} method is called with a key that does not
-+ * exist in the map, the factory is used to create the object. The created
-+ * object will be added to the map using the requested key.
-+ * <p/>
-+ * For instance:
-+ * <pre>
-+ * Factory factory = new Factory() {
-+ *     public Object create() {
-+ *         return new Date();
-+ *     }
-+ * }
-+ * Map lazy = Lazy.map(new HashMap(), factory);
-+ * Object obj = lazy.get("NOW");
-+ * </pre>
-+ * <p/>
-+ * After the above code is executed, <code>obj</code> will contain
-+ * a new <code>Date</code> instance. Furthermore, that <code>Date</code>
-+ * instance is mapped to the "NOW" key in the map.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class LazyMap <K,V> extends AbstractMapDecorator<K, V> implements Map<K, V>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 7990956402564206740L;
-+
-+    /**
-+     * The factory to use to construct elements
-+     */
-+    //protected final Factory<V> factory;
-+
-+    /**
-+     * The factory to use to construct elements
-+     */
-+    protected final Transformer<K, V> transformer;
-+
-+    /**
-+     * Factory method to create a lazily instantiated map.
-+     *
-+     * @param map     the map to decorate, must not be null
-+     * @param factory the factory to use, must not be null
-+     * @throws IllegalArgumentException if map or factory is null
-+     */
-+    public static <K,V> Map<K, V> decorate(Map<K, V> map, Factory<V> factory) {
-+        return new LazyMap<K, V>(map, factory);
-+    }
-+
-+    /**
-+     * Factory method to create a lazily instantiated map.
-+     *
-+     * @param map     		Map to decorate, must not be null
-+     * @param transformer	Transformer to use, must not be null
-+     * @throws IllegalArgumentException if map or transformer is null
-+     */
-+    public static <K,V> Map<K, V> decorate(Map<K, V> map, Transformer<K, V> transformer) {
-+        return new LazyMap<K, V>(map, transformer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map     the map to decorate, must not be null
-+     * @param factory the factory to use, must not be null
-+     * @throws IllegalArgumentException if map or factory is null
-+     */
-+    protected LazyMap(Map<K, V> map, Factory<V> factory) {
-+        super(map);
-+        if (factory == null) {
-+            throw new IllegalArgumentException("Factory must not be null");
-+        }
-+        this.transformer = new FactoryTransformer<K, V>(factory);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map     		Map to decorate, must not be null
-+     * @param transformer	Transformer to use, must not be null
-+     * @throws IllegalArgumentException if map or factory is null
-+     */
-+    protected LazyMap(Map<K, V> map, Transformer<K, V> transformer) {
-+        super(map);
-+        if (transformer == null) {
-+            throw new IllegalArgumentException("Transformer must not be null");
-+        }
-+        this.transformer = transformer;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map<K, V>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public V get(Object key) {
-+        // create value for key if key is not currently in the map
-+        if (map.containsKey(key) == false) {
-+            V value = this.transformer.transform((K) key);
-+            map.put((K) key, value);
-+            return value;
-+        }
-+        return map.get(key);
-+    }
-+
-+    // no need to wrap keySet, entrySet or values as they are views of
-+    // existing map entries - you can't do a map-style get on them.
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/LazySortedMap.java
-@@ -0,0 +1,144 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.util.Comparator;
-+import java.util.SortedMap;
-+
-+import org.apache.commons.collections15.Factory;
-+import org.apache.commons.collections15.Transformer;
-+
-+/**
-+ * Decorates another <code>SortedMap</code> to create objects in the map on demand.
-+ * <p/>
-+ * When the {@link #get(Object)} method is called with a key that does not
-+ * exist in the map, the factory is used to create the object. The created
-+ * object will be added to the map using the requested key.
-+ * <p/>
-+ * For instance:
-+ * <pre>
-+ * Factory factory = new Factory() {
-+ *     public Object create() {
-+ *         return new Date();
-+ *     }
-+ * }
-+ * SortedMap lazy = Lazy.sortedMap(new HashMap(), factory);
-+ * Object obj = lazy.get("NOW");
-+ * </pre>
-+ * <p/>
-+ * After the above code is executed, <code>obj</code> will contain
-+ * a new <code>Date</code> instance. Furthermore, that <code>Date</code>
-+ * instance is mapped to the "NOW" key in the map.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class LazySortedMap <K,V> extends LazyMap<K, V> implements SortedMap<K, V> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 2715322183617658933L;
-+
-+    /**
-+     * Factory method to create a lazily instantiated sorted map.
-+     *
-+     * @param map     the map to decorate, must not be null
-+     * @param factory the factory to use, must not be null
-+     * @throws IllegalArgumentException if map or factory is null
-+     */
-+    public static <K,V> SortedMap<K, V> decorate(SortedMap<K, V> map, Factory<V> factory) {
-+        return new LazySortedMap<K, V>(map, factory);
-+    }
-+
-+    /**
-+     * Factory method to create a lazily instantiated sorted map.
-+     *
-+     * @param map     		Map to decorate, must not be null
-+     * @param transformer	Transformer to use, must not be null
-+     * @throws IllegalArgumentException if map or transformer is null
-+     */
-+    public static <K,V> SortedMap<K, V> decorate(SortedMap<K, V> map, Transformer<K, V> transformer) {
-+        return new LazySortedMap<K, V>(map, transformer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map     the map to decorate, must not be null
-+     * @param factory the factory to use, must not be null
-+     * @throws IllegalArgumentException if map or factory is null
-+     */
-+    protected LazySortedMap(SortedMap<K, V> map, Factory<V> factory) {
-+        super(map, factory);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map     		Map to decorate, must not be null
-+     * @param transformer	Transformer to use, must not be null
-+     * @throws IllegalArgumentException if map or transformer is null
-+     */
-+    protected LazySortedMap(SortedMap<K, V> map, Transformer<K, V> transformer) {
-+        super(map, transformer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected SortedMap<K, V> getSortedMap() {
-+        return (SortedMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K firstKey() {
-+        return getSortedMap().firstKey();
-+    }
-+
-+    public K lastKey() {
-+        return getSortedMap().lastKey();
-+    }
-+
-+    public Comparator<? super K> comparator() {
-+        return getSortedMap().comparator();
-+    }
-+
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        SortedMap<K, V> map = getSortedMap().subMap(fromKey, toKey);
-+        return new LazySortedMap<K, V>(map, transformer);
-+    }
-+
-+    public SortedMap<K, V> headMap(K toKey) {
-+        SortedMap<K, V> map = getSortedMap().headMap(toKey);
-+        return new LazySortedMap<K, V>(map, transformer);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        SortedMap<K, V> map = getSortedMap().tailMap(fromKey);
-+        return new LazySortedMap<K, V>(map, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/LinkedMap.java
-@@ -0,0 +1,276 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+import org.apache.commons.collections15.iterators.UnmodifiableListIterator;
-+import org.apache.commons.collections15.list.UnmodifiableList;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * A <code>Map</code> implementation that maintains the order of the entries.
-+ * In this implementation order is maintained by original insertion.
-+ * <p/>
-+ * This implementation improves on the JDK1.4 LinkedHashMap by adding the
-+ * {@link org.apache.commons.collections15.MapIterator MapIterator}
-+ * functionality, additional convenience methods and allowing
-+ * bidirectional iteration. It also implements <code>OrderedMap</code>.
-+ * In addition, non-interface methods are provided to access the map by index.
-+ * <p/>
-+ * The <code>orderedMapIterator()</code> method provides direct access to a
-+ * bidirectional iterator. The iterators from the other views can also be cast
-+ * to <code>OrderedIterator</code> if required.
-+ * <p/>
-+ * All the available iterators can be reset back to the start by casting to
-+ * <code>ResettableIterator</code> and calling <code>reset()</code>.
-+ * <p/>
-+ * The implementation is also designed to be subclassed, with lots of useful
-+ * methods exposed.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class LinkedMap <K,V> extends AbstractLinkedMap<K, V> implements Serializable, Cloneable {
-+
-+    /**
-+     * Serialisation version
-+     */
-+    private static final long serialVersionUID = 9077234323521161066L;
-+
-+    /**
-+     * Constructs a new empty map with default size and load factor.
-+     */
-+    public LinkedMap() {
-+        super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_THRESHOLD);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     */
-+    public LinkedMap(int initialCapacity) {
-+        super(initialCapacity);
-+    }
-+
-+    /**
-+     * Constructs a new, empty map with the specified initial capacity and
-+     * load factor.
-+     *
-+     * @param initialCapacity the initial capacity
-+     * @param loadFactor      the load factor
-+     * @throws IllegalArgumentException if the initial capacity is less than one
-+     * @throws IllegalArgumentException if the load factor is less than zero
-+     */
-+    public LinkedMap(int initialCapacity, float loadFactor) {
-+        super(initialCapacity, loadFactor);
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     *
-+     * @param map the map to copy
-+     * @throws NullPointerException if the map is null
-+     */
-+    public LinkedMap(Map<? extends K, ? extends V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     *
-+     * @return a shallow clone
-+     */
-+    public Object clone() {
-+        return super.clone();
-+    }
-+
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the key at the specified index.
-+     *
-+     * @param index the index to retrieve
-+     * @return the key at the specified index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public K get(int index) {
-+        return getEntry(index).getKey();
-+    }
-+
-+    /**
-+     * Gets the value at the specified index.
-+     *
-+     * @param index the index to retrieve
-+     * @return the key at the specified index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public V getValue(int index) {
-+        return getEntry(index).getValue();
-+    }
-+
-+    /**
-+     * Gets the index of the specified key.
-+     *
-+     * @param key the key to find the index of
-+     * @return the index, or -1 if not found
-+     */
-+    public int indexOf(Object key) {
-+        int i = 0;
-+        for (LinkEntry entry = header.after; entry != header; entry = entry.after, i++) {
-+            if (isEqualKey(key, entry.getKey())) {
-+                return i;
-+            }
-+        }
-+        return -1;
-+    }
-+
-+    /**
-+     * Removes the element at the specified index.
-+     *
-+     * @param index the index of the object to remove
-+     * @return the previous value corresponding the <code>key</code>,
-+     *         or <code>null</code> if none existed
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public V remove(int index) {
-+        return remove(get(index));
-+    }
-+
-+    /**
-+     * Gets an unmodifiable List view of the keys.
-+     * <p/>
-+     * The returned list is unmodifiable because changes to the values of
-+     * the list (using {@link java.util.ListIterator#set(Object)}) will
-+     * effectively remove the value from the list and reinsert that value at
-+     * the end of the list, which is an unexpected side effect of changing the
-+     * value of a list.  This occurs because changing the key, changes when the
-+     * mapping is added to the map and thus where it appears in the list.
-+     * <p/>
-+     * An alternative to this method is to use {@link #keySet()}.
-+     *
-+     * @return The ordered list of keys.
-+     * @see #keySet()
-+     */
-+    public List<K> asList() {
-+        return new LinkedMapList<K, V>(this);
-+    }
-+
-+    /**
-+     * List view of map.
-+     */
-+    static class LinkedMapList <K,V> extends AbstractList<K> {
-+
-+        final LinkedMap<K, V> parent;
-+
-+        LinkedMapList(LinkedMap<K, V> parent) {
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return parent.size();
-+        }
-+
-+        public K get(int index) {
-+            return parent.get(index);
-+        }
-+
-+        public boolean contains(Object obj) {
-+            return parent.containsKey(obj);
-+        }
-+
-+        public int indexOf(Object obj) {
-+            return parent.indexOf(obj);
-+        }
-+
-+        public int lastIndexOf(Object obj) {
-+            return parent.indexOf(obj);
-+        }
-+
-+        public boolean containsAll(Collection<?> coll) {
-+            return parent.keySet().containsAll(coll);
-+        }
-+
-+        public K remove(int index) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public boolean remove(Object obj) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public boolean removeAll(Collection<?> coll) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public boolean retainAll(Collection<?> coll) {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public void clear() {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public Object[] toArray() {
-+            return parent.keySet().toArray();
-+        }
-+
-+        public <T> T[] toArray(T[] array) {
-+            return parent.keySet().toArray(array);
-+        }
-+
-+        public Iterator<K> iterator() {
-+            return UnmodifiableIterator.decorate(parent.keySet().iterator());
-+        }
-+
-+        public ListIterator<K> listIterator() {
-+            return UnmodifiableListIterator.decorate(super.listIterator());
-+        }
-+
-+        public ListIterator<K> listIterator(int fromIndex) {
-+            return UnmodifiableListIterator.decorate(super.listIterator(fromIndex));
-+        }
-+
-+        public List<K> subList(int fromIndexInclusive, int toIndexExclusive) {
-+            return UnmodifiableList.decorate(super.subList(fromIndexInclusive, toIndexExclusive));
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/ListOrderedMap.java
-@@ -0,0 +1,592 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.OrderedMap;
-+import org.apache.commons.collections15.OrderedMapIterator;
-+import org.apache.commons.collections15.ResettableIterator;
-+import org.apache.commons.collections15.iterators.AbstractIteratorDecorator;
-+import org.apache.commons.collections15.keyvalue.AbstractMapEntry;
-+import org.apache.commons.collections15.list.UnmodifiableList;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * Decorates a <code>Map</code> to ensure that the order of addition is retained
-+ * using a <code>List</code> to maintain order.
-+ * <p/>
-+ * The order will be used via the iterators and toArray methods on the views.
-+ * The order is also returned by the <code>MapIterator</code>.
-+ * The <code>orderedMapIterator()</code> method accesses an iterator that can
-+ * iterate both forwards and backwards through the map.
-+ * In addition, non-interface methods are provided to access the map by index.
-+ * <p/>
-+ * If an object is added to the Map for a second time, it will remain in the
-+ * original position in the iteration.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Henri Yandell
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ListOrderedMap <K,V> extends AbstractMapDecorator<K, V> implements OrderedMap<K, V>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 2728177751851003750L;
-+
-+    /**
-+     * Internal list to hold the sequence of objects
-+     */
-+    protected final List<K> insertOrder = new ArrayList<K>();
-+
-+    /**
-+     * Factory method to create an ordered map.
-+     * <p/>
-+     * An <code>ArrayList</code> is used to retain order.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> OrderedMap<K, V> decorate(Map<K, V> map) {
-+        return new ListOrderedMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new empty <code>ListOrderedMap</code> that decorates
-+     * a <code>HashMap</code>.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    public ListOrderedMap() {
-+        this(new HashMap<K, V>());
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    protected ListOrderedMap(Map<K, V> map) {
-+        super(map);
-+        insertOrder.addAll(getMap().keySet());
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map<K, V>) in.readObject();
-+    }
-+
-+    // Implement OrderedMap
-+    //-----------------------------------------------------------------------
-+    public MapIterator<K, V> mapIterator() {
-+        return orderedMapIterator();
-+    }
-+
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        return new ListOrderedMapIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Gets the first key in this map by insert order.
-+     *
-+     * @return the first key currently in this map
-+     * @throws NoSuchElementException if this map is empty
-+     */
-+    public K firstKey() {
-+        if (size() == 0) {
-+            throw new NoSuchElementException("Map is empty");
-+        }
-+        return insertOrder.get(0);
-+    }
-+
-+    /**
-+     * Gets the last key in this map by insert order.
-+     *
-+     * @return the last key currently in this map
-+     * @throws NoSuchElementException if this map is empty
-+     */
-+    public K lastKey() {
-+        if (size() == 0) {
-+            throw new NoSuchElementException("Map is empty");
-+        }
-+        return insertOrder.get(size() - 1);
-+    }
-+
-+    /**
-+     * Gets the next key to the one specified using insert order.
-+     * This method performs a list search to find the key and is O(n).
-+     *
-+     * @param key the key to find previous for
-+     * @return the next key, null if no match or at start
-+     */
-+    public K nextKey(K key) {
-+        int index = insertOrder.indexOf(key);
-+        if (index >= 0 && index < size() - 1) {
-+            return insertOrder.get(index + 1);
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets the previous key to the one specified using insert order.
-+     * This method performs a list search to find the key and is O(n).
-+     *
-+     * @param key the key to find previous for
-+     * @return the previous key, null if no match or at start
-+     */
-+    public K previousKey(K key) {
-+        int index = insertOrder.indexOf(key);
-+        if (index > 0) {
-+            return insertOrder.get(index - 1);
-+        }
-+        return null;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public V put(K key, V value) {
-+        if (getMap().containsKey(key)) {
-+            // re-adding doesn't change order
-+            return getMap().put(key, value);
-+        } else {
-+            // first add, so add to both map and list
-+            V result = getMap().put(key, value);
-+            insertOrder.add(key);
-+            return result;
-+        }
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            put((K) entry.getKey(), (V) entry.getValue());
-+        }
-+    }
-+
-+    public V remove(Object key) {
-+        V result = getMap().remove(key);
-+        insertOrder.remove(key);
-+        return result;
-+    }
-+
-+    public void clear() {
-+        getMap().clear();
-+        insertOrder.clear();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Set<K> keySet() {
-+        return new KeySetView<K, V>(this);
-+    }
-+
-+    public Collection<V> values() {
-+        return new ValuesView<K, V>(this);
-+    }
-+
-+    public Set<Map.Entry<K,V>> entrySet() {
-+        return new EntrySetView<K,V>(this, this.insertOrder);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Returns the Map as a string.
-+     *
-+     * @return the Map as a String
-+     */
-+    public String toString() {
-+        if (isEmpty()) {
-+            return "{}";
-+        }
-+        StringBuffer buf = new StringBuffer();
-+        buf.append('{');
-+        boolean first = true;
-+        Iterator it = entrySet().iterator();
-+        while (it.hasNext()) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            Object key = entry.getKey();
-+            Object value = entry.getValue();
-+            if (first) {
-+                first = false;
-+            } else {
-+                buf.append(", ");
-+            }
-+            buf.append(key == this ? "(this Map)" : key);
-+            buf.append('=');
-+            buf.append(value == this ? "(this Map)" : value);
-+        }
-+        buf.append('}');
-+        return buf.toString();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the key at the specified index.
-+     *
-+     * @param index the index to retrieve
-+     * @return the key at the specified index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public K get(int index) {
-+        return insertOrder.get(index);
-+    }
-+
-+    /**
-+     * Gets the value at the specified index.
-+     *
-+     * @param index the index to retrieve
-+     * @return the key at the specified index
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public V getValue(int index) {
-+        return get(insertOrder.get(index));
-+    }
-+
-+    /**
-+     * Gets the index of the specified key.
-+     *
-+     * @param key the key to find the index of
-+     * @return the index, or -1 if not found
-+     */
-+    public int indexOf(Object key) {
-+        return insertOrder.indexOf(key);
-+    }
-+
-+    /**
-+     * Removes the element at the specified index.
-+     *
-+     * @param index the index of the object to remove
-+     * @return the previous value corresponding the <code>key</code>,
-+     *         or <code>null</code> if none existed
-+     * @throws IndexOutOfBoundsException if the index is invalid
-+     */
-+    public Object remove(int index) {
-+        return remove(get(index));
-+    }
-+
-+    /**
-+     * Gets an unmodifiable List view of the keys which changes as the map changes.
-+     * <p/>
-+     * The returned list is unmodifiable because changes to the values of
-+     * the list (using {@link java.util.ListIterator#set(Object)}) will
-+     * effectively remove the value from the list and reinsert that value at
-+     * the end of the list, which is an unexpected side effect of changing the
-+     * value of a list.  This occurs because changing the key, changes when the
-+     * mapping is added to the map and thus where it appears in the list.
-+     * <p/>
-+     * An alternative to this method is to use {@link #keySet()}.
-+     *
-+     * @return The ordered list of keys.
-+     * @see #keySet()
-+     */
-+    public List<K> asList() {
-+        return UnmodifiableList.decorate(insertOrder);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    static class ValuesView <K,V> extends AbstractCollection<V> {
-+        private final ListOrderedMap<K, V> parent;
-+
-+        ValuesView(ListOrderedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return this.parent.size();
-+        }
-+
-+        public boolean contains(Object value) {
-+            return this.parent.containsValue(value);
-+        }
-+
-+        public void clear() {
-+            this.parent.clear();
-+        }
-+
-+        public Iterator<V> iterator() {
-+            return new AbstractIteratorDecorator(parent.entrySet().iterator()) {
-+                public Object next() {
-+                    return ((Map.Entry) iterator.next()).getValue();
-+                }
-+            };
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    static class KeySetView <K,V> extends AbstractSet<K> {
-+        private final ListOrderedMap<K, V> parent;
-+
-+        KeySetView(ListOrderedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return this.parent.size();
-+        }
-+
-+        public boolean contains(Object value) {
-+            return this.parent.containsKey(value);
-+        }
-+
-+        public void clear() {
-+            this.parent.clear();
-+        }
-+
-+        public Iterator<K> iterator() {
-+            final Iterator<Map.Entry<K, V>> entryIterator = parent.entrySet().iterator();
-+            return new Iterator<K>() {
-+                public K next() {
-+                    return entryIterator.next().getKey();
-+                }
-+
-+                public boolean hasNext() {
-+                    return entryIterator.hasNext();
-+                }
-+
-+                public void remove() {
-+                    entryIterator.remove();
-+                }
-+            };
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    static class EntrySetView <K,V> extends AbstractSet<Map.Entry<K, V>> {
-+        private final ListOrderedMap<K, V> parent;
-+        private final List<K> insertOrder;
-+        private Set<Map.Entry<K, V>> entrySet;
-+
-+        public EntrySetView(ListOrderedMap<K, V> parent, List<K> insertOrder) {
-+            super();
-+            this.parent = parent;
-+            this.insertOrder = insertOrder;
-+        }
-+
-+        private Set<Map.Entry<K, V>> getEntrySet() {
-+            if (entrySet == null) {
-+                entrySet = parent.getMap().entrySet();
-+            }
-+            return entrySet;
-+        }
-+
-+        public int size() {
-+            return this.parent.size();
-+        }
-+
-+        public boolean isEmpty() {
-+            return this.parent.isEmpty();
-+        }
-+
-+        public boolean contains(Object obj) {
-+            return getEntrySet().contains(obj);
-+        }
-+
-+        public boolean containsAll(Collection<?> coll) {
-+            return getEntrySet().containsAll(coll);
-+        }
-+
-+        public boolean remove(Object obj) {
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            if (getEntrySet().contains(obj)) {
-+                Object key = ((Map.Entry) obj).getKey();
-+                parent.remove(key);
-+                return true;
-+            }
-+            return false;
-+        }
-+
-+        public void clear() {
-+            this.parent.clear();
-+        }
-+
-+        public boolean equals(Object obj) {
-+            if (obj == this) {
-+                return true;
-+            }
-+            return getEntrySet().equals(obj);
-+        }
-+
-+        public int hashCode() {
-+            return getEntrySet().hashCode();
-+        }
-+
-+        public String toString() {
-+            return getEntrySet().toString();
-+        }
-+
-+        public Iterator<Map.Entry<K, V>> iterator() {
-+            return new ListOrderedIterator<K, V>(parent, insertOrder);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    static class ListOrderedIterator <K,V> implements Iterator<Map.Entry<K, V>> {
-+        private final ListOrderedMap<K, V> parent;
-+        private K last = null;
-+        private Iterator<K> listIterator;
-+
-+        ListOrderedIterator(ListOrderedMap<K, V> parent, List<K> insertOrder) {
-+            listIterator = insertOrder.iterator();
-+            this.parent = parent;
-+        }
-+
-+        public Map.Entry<K, V> next() {
-+            last = listIterator.next();
-+            return new ListOrderedMapEntry<K, V>(parent, last);
-+        }
-+
-+        public void remove() {
-+            listIterator.remove();
-+            parent.getMap().remove(last);
-+        }
-+
-+        public boolean hasNext() {
-+            return listIterator.hasNext();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    static class ListOrderedMapEntry <K,V> extends AbstractMapEntry<K, V> {
-+        private final ListOrderedMap<K, V> parent;
-+
-+        ListOrderedMapEntry(ListOrderedMap<K, V> parent, K key) {
-+            super(key, null);
-+            this.parent = parent;
-+        }
-+
-+        public V getValue() {
-+            return parent.get(key);
-+        }
-+
-+        public V setValue(V value) {
-+            return parent.getMap().put(key, value);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    static class ListOrderedMapIterator <K,V> implements OrderedMapIterator<K, V>, ResettableIterator<K> {
-+        private final ListOrderedMap<K, V> parent;
-+        private ListIterator<K> iterator;
-+        private K last = null;
-+        private boolean readable = false;
-+
-+        ListOrderedMapIterator(ListOrderedMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+            this.iterator = parent.insertOrder.listIterator();
-+        }
-+
-+        public boolean hasNext() {
-+            return iterator.hasNext();
-+        }
-+
-+        public K next() {
-+            last = iterator.next();
-+            readable = true;
-+            return last;
-+        }
-+
-+        public boolean hasPrevious() {
-+            return iterator.hasPrevious();
-+        }
-+
-+        public K previous() {
-+            last = iterator.previous();
-+            readable = true;
-+            return last;
-+        }
-+
-+        public void remove() {
-+            if (readable == false) {
-+                throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
-+            }
-+            iterator.remove();
-+            parent.map.remove(last);
-+            readable = false;
-+        }
-+
-+        public K getKey() {
-+            if (readable == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
-+            }
-+            return last;
-+        }
-+
-+        public V getValue() {
-+            if (readable == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
-+            }
-+            return parent.get(last);
-+        }
-+
-+        public V setValue(V value) {
-+            if (readable == false) {
-+                throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
-+            }
-+            return parent.map.put(last, value);
-+        }
-+
-+        public void reset() {
-+            iterator = parent.insertOrder.listIterator();
-+            last = null;
-+            readable = false;
-+        }
-+
-+        public String toString() {
-+            if (readable == true) {
-+                return "Iterator[" + getKey() + "=" + getValue() + "]";
-+            } else {
-+                return "Iterator[]";
-+            }
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/MultiKeyMap.java
-@@ -0,0 +1,488 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.IterableMap;
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.keyvalue.MultiKey;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * A <code>Map</code> implementation that uses multiple keys to map the value.
-+ * <p/>
-+ * This class is the most efficient way to uses multiple keys to map to a value.
-+ * The best way to use this class is via the additional map-style methods.
-+ * These provide <code>get</code>, <code>containsKey</code>, <code>put</code> and
-+ * <code>remove</code> for individual keys which operate without extra object creation.
-+ * <p/>
-+ * The additional methods are the main interface of this map.
-+ * As such, you will not normally hold this map in a variable of type <code>Map</code>.
-+ * <p/>
-+ * The normal map methods take in and return a {@link MultiKey}.
-+ * If you try to use <code>put()</code> with any other object type a
-+ * <code>ClassCastException</code> is thrown. If you try to use <code>null</code> as
-+ * the key in <code>put()</code> a <code>NullPointerException</code> is thrown.
-+ * <p/>
-+ * This map is implemented as a decorator of a <code>AbstractHashedMap</code> which
-+ * enables extra behaviour to be added easily.
-+ * <ul>
-+ * <li><code>MultiKeyMap.decorate(new LinkedMap())</code> creates an ordered map.
-+ * <li><code>MultiKeyMap.decorate(new LRUMap())</code> creates an least recently used map.
-+ * <li><code>MultiKeyMap.decorate(new ReferenceMap())</code> creates a garbage collector sensitive map.
-+ * </ul>
-+ * Note that <code>IdentityMap</code> and <code>ReferenceIdentityMap</code> are unsuitable
-+ * for use as the key comparison would work on the whole MultiKey, not the elements within.
-+ * <p/>
-+ * As an example, consider a least recently used cache that uses a String airline code
-+ * and a Locale to lookup the airline's name:
-+ * <pre>
-+ * private MultiKeyMap cache = MultiKeyMap.decorate(new LRUMap(50));
-+ * <p/>
-+ * public String getAirlineName(String code, String locale) {
-+ *   String name = (String) cache.get(code, locale);
-+ *   if (name == null) {
-+ *     name = getAirlineNameFromDB(code, locale);
-+ *     cache.put(code, locale, name);
-+ *   }
-+ *   return name;
-+ * }
-+ * </pre>
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.1
-+ */
-+public class MultiKeyMap <K,V> implements IterableMap<MultiKey<K>, V>, Serializable {
-+
-+    /**
-+     * Serialisation version
-+     */
-+    private static final long serialVersionUID = -1788199231038721040L;
-+
-+    /**
-+     * The decorated map
-+     */
-+    protected final AbstractHashedMap<MultiKey<K>, V> map;
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Decorates the specified map to add the MultiKeyMap API and fast query.
-+     * The map must not be null and must be empty.
-+     *
-+     * @param map the map to decorate, not null
-+     * @throws IllegalArgumentException if the map is null or not empty
-+     */
-+    public static <K,V> MultiKeyMap<K, V> decorate(AbstractHashedMap<MultiKey<K>, V> map) {
-+        if (map == null) {
-+            throw new IllegalArgumentException("Map must not be null");
-+        }
-+        if (map.size() > 0) {
-+            throw new IllegalArgumentException("Map must be empty");
-+        }
-+        return new MultiKeyMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------    
-+    /**
-+     * Constructs a new MultiKeyMap that decorates a <code>HashedMap</code>.
-+     */
-+    public MultiKeyMap() {
-+        super();
-+        map = new HashedMap<MultiKey<K>, V>();
-+    }
-+
-+    /**
-+     * Constructor that decorates the specified map and is called from
-+     * {@link #decorate(AbstractHashedMap)}.
-+     * The map must not be null and should be empty or only contain valid keys.
-+     * This constructor performs no validation.
-+     *
-+     * @param map the map to decorate
-+     */
-+    protected MultiKeyMap(AbstractHashedMap<MultiKey<K>, V> map) {
-+        super();
-+        this.map = map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the value mapped to the specified multi-key.
-+     *
-+     * @param keys the keys
-+     * @return the mapped value, null if no match
-+     */
-+    public V get(K... keys) {
-+        int hashCode = hash(keys);
-+        AbstractHashedMap.HashEntry<MultiKey<K>, V> entry = map.data[map.hashIndex(hashCode, map.data.length)];
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(entry, keys)) {
-+                return entry.getValue();
-+            }
-+            entry = entry.next;
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Checks whether the map contains the specified multi-key.
-+     *
-+     * @param keys the keys
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsKey(K... keys) {
-+        int hashCode = hash(keys);
-+        AbstractHashedMap.HashEntry<MultiKey<K>, V> entry = map.data[map.hashIndex(hashCode, map.data.length)];
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(entry, keys)) {
-+                return true;
-+            }
-+            entry = entry.next;
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * For backwards compatibility, makes a call to the new varargs {@link MultiKeyMap#putMultiKey}
-+     */
-+    public V put(K key1, K key2, V value) {
-+        return putMultiKey(value, key1, key2);
-+    }
-+
-+    /**
-+     * For backwards compatibility, makes a call to the new varargs {@link MultiKeyMap#putMultiKey}
-+     */
-+    public V put(K key1, K key2, K key3, V value) {
-+        return putMultiKey(value, key1, key2, key3);
-+    }
-+
-+    /**
-+     * For backwards compatibility, makes a call to the new varargs {@link MultiKeyMap#putMultiKey}
-+     */
-+    public V put(K key1, K key2, K key3, K key4, V value) {
-+        return putMultiKey(value, key1, key2, key3, key4);
-+    }
-+
-+    /**
-+     * For backwards compatibility, makes a call to the new varargs {@link MultiKeyMap#putMultiKey}
-+     */
-+    public V put(K key1, K key2, K key3, K key4, K key5, V value) {
-+        return putMultiKey(value, key1, key2, key3, key4, key5);
-+    }
-+
-+    /**
-+     * Stores the value against the specified multi-key.
-+     *
-+     * @param value the value to store
-+     * @param keys  the keys
-+     * @return the value previously mapped to this combined key, null if none
-+     */
-+    public V putMultiKey(V value, K... keys) {
-+        int hashCode = hash(keys);
-+        int index = map.hashIndex(hashCode, map.data.length);
-+        AbstractHashedMap.HashEntry<MultiKey<K>, V> entry = map.data[index];
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(entry, keys)) {
-+                V oldValue = entry.getValue();
-+                map.updateEntry(entry, value);
-+                return oldValue;
-+            }
-+            entry = entry.next;
-+        }
-+
-+        map.addMapping(index, hashCode, new MultiKey<K>(keys), value);
-+        return null;
-+    }
-+
-+    /**
-+     * Removes the specified multi-key from this map.
-+     *
-+     * @param keys the keys
-+     * @return the value mapped to the removed key, null if key not in map
-+     */
-+    public Object remove(K... keys) {
-+        int hashCode = hash(keys);
-+        int index = map.hashIndex(hashCode, map.data.length);
-+        AbstractHashedMap.HashEntry<MultiKey<K>, V> entry = map.data[index];
-+        AbstractHashedMap.HashEntry<MultiKey<K>, V> previous = null;
-+        while (entry != null) {
-+            if (entry.hashCode == hashCode && isEqualKey(entry, keys)) {
-+                Object oldValue = entry.getValue();
-+                map.removeMapping(entry, index, previous);
-+                return oldValue;
-+            }
-+            previous = entry;
-+            entry = entry.next;
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets the hash code for the specified multi-key.
-+     *
-+     * @param keys the keys
-+     * @return the hash code
-+     */
-+    protected int hash(K... keys) {
-+        int h = 0;
-+        for (int i = 0; i < keys.length; i++) {
-+            K key = keys[i];
-+            if (key != null) {
-+                h ^= key.hashCode();
-+            }
-+        }
-+        h += ~(h << 9);
-+        h ^= (h >>> 14);
-+        h += (h << 4);
-+        h ^= (h >>> 10);
-+        return h;
-+    }
-+
-+    /**
-+     * Is the key equal to the combined key.
-+     *
-+     * @param entry the entry to compare to
-+     * @param keys  the keys
-+     * @return true if the key matches
-+     */
-+    protected boolean isEqualKey(AbstractHashedMap.HashEntry<MultiKey<K>, V> entry, K... keys) {
-+        MultiKey multi = (MultiKey) entry.getKey();
-+        if (multi.size() != keys.length) {
-+            return false;
-+        } else {
-+            for (int i = 0; i < keys.length; i++) {
-+                K key = keys[i];
-+                if ((key == null ? multi.getKey(i) != null : !key.equals(multi.getKey(i)))) {
-+                    return false;
-+                }
-+            }
-+        }
-+        return true;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Removes all mappings where the first key is that specified.
-+     * <p/>
-+     * This method removes all the mappings where the <code>MultiKey</code>
-+     * has one or more keys, and the first matches that specified.
-+     *
-+     * @param key1 the first key
-+     * @return true if any elements were removed
-+     */
-+    public boolean removeAll(Object key1) {
-+        boolean modified = false;
-+        MapIterator it = mapIterator();
-+        while (it.hasNext()) {
-+            MultiKey multi = (MultiKey) it.next();
-+            if (multi.size() >= 1 && (key1 == null ? multi.getKey(0) == null : key1.equals(multi.getKey(0)))) {
-+                it.remove();
-+                modified = true;
-+            }
-+        }
-+        return modified;
-+    }
-+
-+    /**
-+     * Removes all mappings where the first two keys are those specified.
-+     * <p/>
-+     * This method removes all the mappings where the <code>MultiKey</code>
-+     * has two or more keys, and the first two match those specified.
-+     *
-+     * @param key1 the first key
-+     * @param key2 the second key
-+     * @return true if any elements were removed
-+     */
-+    public boolean removeAll(Object key1, Object key2) {
-+        boolean modified = false;
-+        MapIterator it = mapIterator();
-+        while (it.hasNext()) {
-+            MultiKey multi = (MultiKey) it.next();
-+            if (multi.size() >= 2 && (key1 == null ? multi.getKey(0) == null : key1.equals(multi.getKey(0))) && (key2 == null ? multi.getKey(1) == null : key2.equals(multi.getKey(1)))) {
-+                it.remove();
-+                modified = true;
-+            }
-+        }
-+        return modified;
-+    }
-+
-+    /**
-+     * Removes all mappings where the first three keys are those specified.
-+     * <p/>
-+     * This method removes all the mappings where the <code>MultiKey</code>
-+     * has three or more keys, and the first three match those specified.
-+     *
-+     * @param key1 the first key
-+     * @param key2 the second key
-+     * @param key3 the third key
-+     * @return true if any elements were removed
-+     */
-+    public boolean removeAll(Object key1, Object key2, Object key3) {
-+        boolean modified = false;
-+        MapIterator it = mapIterator();
-+        while (it.hasNext()) {
-+            MultiKey multi = (MultiKey) it.next();
-+            if (multi.size() >= 3 && (key1 == null ? multi.getKey(0) == null : key1.equals(multi.getKey(0))) && (key2 == null ? multi.getKey(1) == null : key2.equals(multi.getKey(1))) && (key3 == null ? multi.getKey(2) == null : key3.equals(multi.getKey(2)))) {
-+                it.remove();
-+                modified = true;
-+            }
-+        }
-+        return modified;
-+    }
-+
-+    /**
-+     * Removes all mappings where the first four keys are those specified.
-+     * <p/>
-+     * This method removes all the mappings where the <code>MultiKey</code>
-+     * has four or more keys, and the first four match those specified.
-+     *
-+     * @param key1 the first key
-+     * @param key2 the second key
-+     * @param key3 the third key
-+     * @param key4 the fourth key
-+     * @return true if any elements were removed
-+     */
-+    public boolean removeAll(Object key1, Object key2, Object key3, Object key4) {
-+        boolean modified = false;
-+        MapIterator it = mapIterator();
-+        while (it.hasNext()) {
-+            MultiKey multi = (MultiKey) it.next();
-+            if (multi.size() >= 4 && (key1 == null ? multi.getKey(0) == null : key1.equals(multi.getKey(0))) && (key2 == null ? multi.getKey(1) == null : key2.equals(multi.getKey(1))) && (key3 == null ? multi.getKey(2) == null : key3.equals(multi.getKey(2))) && (key4 == null ? multi.getKey(3) == null : key4.equals(multi.getKey(3)))) {
-+                it.remove();
-+                modified = true;
-+            }
-+        }
-+        return modified;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Check to ensure that input keys are valid MultiKey objects.
-+     *
-+     * @param key the key to check
-+     */
-+    protected void checkKey(Object key) {
-+        if (key == null) {
-+            throw new NullPointerException("Key must not be null");
-+        }
-+    }
-+
-+    /**
-+     * Clones the map without cloning the keys or values.
-+     *
-+     * @return a shallow clone
-+     */
-+    public Object clone() {
-+        return new MultiKeyMap((AbstractHashedMap) map.clone());
-+    }
-+
-+    /**
-+     * Puts the key and value into the map, where the key must be a non-null
-+     * MultiKey object.
-+     *
-+     * @param key   the non-null MultiKey object
-+     * @param value the value to store
-+     * @return the previous value for the key
-+     * @throws NullPointerException if the key is null
-+     * @throws ClassCastException   if the key is not a MultiKey
-+     */
-+    public V put(MultiKey<K> key, V value) {
-+        checkKey(key);
-+        return map.put(key, value);
-+    }
-+
-+    /**
-+     * Puts all the keys and values into this map.
-+     * Each key must be non-null and a MultiKey object.
-+     *
-+     * @param mapToCopy the map to copy in.
-+     * @throws NullPointerException if the mapToCopy or any key within is null
-+     * @throws ClassCastException   if any key is not a MultiKey
-+     */
-+    public void putAll(Map<? extends MultiKey<K>, ? extends V> mapToCopy) {
-+        for (Iterator it = mapToCopy.keySet().iterator(); it.hasNext();) {
-+            Object key = it.next();
-+            checkKey(key);
-+        }
-+        map.putAll(mapToCopy);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public MapIterator mapIterator() {
-+        return map.mapIterator();
-+    }
-+
-+    public int size() {
-+        return map.size();
-+    }
-+
-+    public boolean isEmpty() {
-+        return map.isEmpty();
-+    }
-+
-+    public boolean containsKey(Object key) {
-+        return map.containsKey(key);
-+    }
-+
-+    public boolean containsValue(Object value) {
-+        return map.containsValue(value);
-+    }
-+
-+    public V get(Object key) {
-+        return map.get(key);
-+    }
-+
-+    public V remove(Object key) {
-+        return map.remove(key);
-+    }
-+
-+    public void clear() {
-+        map.clear();
-+    }
-+
-+    public Set keySet() {
-+        return map.keySet();
-+    }
-+
-+    public Collection values() {
-+        return map.values();
-+    }
-+
-+    public Set entrySet() {
-+        return map.entrySet();
-+    }
-+
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        return map.equals(obj);
-+    }
-+
-+    public int hashCode() {
-+        return map.hashCode();
-+    }
-+
-+    public String toString() {
-+        return map.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/PredicatedMap.java
-@@ -0,0 +1,184 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Iterator;
-+import java.util.Map;
-+
-+/**
-+ * Decorates another <code>Map</code> to validate that additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This map exists to provide validation for the decorated map.
-+ * It is normally created to decorate an empty map.
-+ * If an object cannot be added to the map, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null keys are added to the map.
-+ * <pre>Map map = PredicatedSet.decorate(new HashMap(), NotNullPredicate.INSTANCE, null);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedMap <K,V> extends AbstractInputCheckedMapDecorator<K, V> implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 7412622456128415156L;
-+
-+    /**
-+     * The key predicate to use
-+     */
-+    protected final Predicate<? super K> keyPredicate;
-+    /**
-+     * The value predicate to use
-+     */
-+    protected final Predicate<? super V> valuePredicate;
-+
-+    /**
-+     * Factory method to create a predicated (validating) map.
-+     * <p/>
-+     * If there are any elements already in the list being decorated, they
-+     * are validated.
-+     *
-+     * @param map            the map to decorate, must not be null
-+     * @param keyPredicate   the predicate to validate the keys, null means no check
-+     * @param valuePredicate the predicate to validate to values, null means no check
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    public static <K,V> Map<K, V> decorate(Map<K, V> map, Predicate<? super K> keyPredicate, Predicate<? super V> valuePredicate) {
-+        return new PredicatedMap<K, V>(map, keyPredicate, valuePredicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map            the map to decorate, must not be null
-+     * @param keyPredicate   the predicate to validate the keys, null means no check
-+     * @param valuePredicate the predicate to validate to values, null means no check
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    protected PredicatedMap(Map<K, V> map, Predicate<? super K> keyPredicate, Predicate<? super V> valuePredicate) {
-+        super(map);
-+        this.keyPredicate = keyPredicate;
-+        this.valuePredicate = valuePredicate;
-+
-+        Iterator<Map.Entry<K, V>> it = map.entrySet().iterator();
-+        while (it.hasNext()) {
-+            Map.Entry<K, V> entry = it.next();
-+            K key = entry.getKey();
-+            V value = entry.getValue();
-+            validate(key, value);
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map<K, V>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Validates a key value pair.
-+     *
-+     * @param key   the key to validate
-+     * @param value the value to validate
-+     * @throws IllegalArgumentException if invalid
-+     */
-+    protected void validate(K key, V value) {
-+        if (keyPredicate != null && keyPredicate.evaluate(key) == false) {
-+            throw new IllegalArgumentException("Cannot add key - Predicate rejected it");
-+        }
-+        if (valuePredicate != null && valuePredicate.evaluate(value) == false) {
-+            throw new IllegalArgumentException("Cannot add value - Predicate rejected it");
-+        }
-+    }
-+
-+    /**
-+     * Override to validate an object set into the map via <code>setValue</code>.
-+     *
-+     * @param value the value to validate
-+     * @throws IllegalArgumentException if invalid
-+     * @since Commons Collections 3.1
-+     */
-+    protected V checkSetValue(V value) {
-+        if (valuePredicate.evaluate(value) == false) {
-+            throw new IllegalArgumentException("Cannot set value - Predicate rejected it");
-+        }
-+        return value;
-+    }
-+
-+    /**
-+     * Override to only return true when there is a value transformer.
-+     *
-+     * @return true if a value predicate is in use
-+     * @since Commons Collections 3.1
-+     */
-+    protected boolean isSetValueChecking() {
-+        return (valuePredicate != null);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public V put(K key, V value) {
-+        validate(key, value);
-+        return map.put(key, value);
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        Iterator it = mapToCopy.entrySet().iterator();
-+        while (it.hasNext()) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            K key = (K) entry.getKey();
-+            V value = (V) entry.getValue();
-+            validate(key, value);
-+        }
-+        map.putAll(mapToCopy);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/PredicatedSortedMap.java
-@@ -0,0 +1,115 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.util.Comparator;
-+import java.util.SortedMap;
-+
-+/**
-+ * Decorates another <code>SortedMap </code> to validate that additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This map exists to provide validation for the decorated map.
-+ * It is normally created to decorate an empty map.
-+ * If an object cannot be added to the map, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null keys are added to the map.
-+ * <pre>SortedMap map = PredicatedSortedSet.decorate(new TreeMap(), NotNullPredicate.INSTANCE, null);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedSortedMap <K,V> extends PredicatedMap<K, V> implements SortedMap<K, V> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 3359846175935304332L;
-+
-+    /**
-+     * Factory method to create a predicated (validating) sorted map.
-+     * <p/>
-+     * If there are any elements already in the list being decorated, they
-+     * are validated.
-+     *
-+     * @param map            the map to decorate, must not be null
-+     * @param keyPredicate   the predicate to validate the keys, null means no check
-+     * @param valuePredicate the predicate to validate to values, null means no check
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    public static <K,V> SortedMap<K, V> decorate(SortedMap<K, V> map, Predicate<? super K> keyPredicate, Predicate<? super V> valuePredicate) {
-+        return new PredicatedSortedMap<K, V>(map, keyPredicate, valuePredicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map            the map to decorate, must not be null
-+     * @param keyPredicate   the predicate to validate the keys, null means no check
-+     * @param valuePredicate the predicate to validate to values, null means no check
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    protected PredicatedSortedMap(SortedMap<K, V> map, Predicate<? super K> keyPredicate, Predicate<? super V> valuePredicate) {
-+        super(map, keyPredicate, valuePredicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected SortedMap<K, V> getSortedMap() {
-+        return (SortedMap<K, V>) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K firstKey() {
-+        return getSortedMap().firstKey();
-+    }
-+
-+    public K lastKey() {
-+        return getSortedMap().lastKey();
-+    }
-+
-+    public Comparator<? super K> comparator() {
-+        return getSortedMap().comparator();
-+    }
-+
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        SortedMap<K, V> map = getSortedMap().subMap(fromKey, toKey);
-+        return new PredicatedSortedMap<K, V>(map, keyPredicate, valuePredicate);
-+    }
-+
-+    public SortedMap<K, V> headMap(K toKey) {
-+        SortedMap map = getSortedMap().headMap(toKey);
-+        return new PredicatedSortedMap<K, V>(map, keyPredicate, valuePredicate);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        SortedMap<K, V> map = getSortedMap().tailMap(fromKey);
-+        return new PredicatedSortedMap<K, V>(map, keyPredicate, valuePredicate);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/ReferenceIdentityMap.java
-@@ -0,0 +1,212 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.lang.ref.Reference;
-+
-+/**
-+ * A <code>Map</code> implementation that allows mappings to be
-+ * removed by the garbage collector and matches keys and values based
-+ * on <code>==</code> not <code>equals()</code>.
-+ * <p/>
-+ * <p/>
-+ * When you construct a <code>ReferenceIdentityMap</code>, you can specify what kind
-+ * of references are used to store the map's keys and values.
-+ * If non-hard references are used, then the garbage collector can remove
-+ * mappings if a key or value becomes unreachable, or if the JVM's memory is
-+ * running low. For information on how the different reference types behave,
-+ * see {@link Reference}.
-+ * <p/>
-+ * Different types of references can be specified for keys and values.
-+ * The default constructor uses hard keys and soft values, providing a
-+ * memory-sensitive cache.
-+ * <p/>
-+ * This map is similar to
-+ * {@link org.apache.commons.collections15.map.ReferenceMap ReferenceMap}.
-+ * It differs in that keys and values in this class are compared using <code>==</code>.
-+ * <p/>
-+ * This map will violate the detail of various Map and map view contracts.
-+ * As a general rule, don't compare this map to other maps.
-+ * <p/>
-+ * This {@link java.util.Map} implementation does <i>not</i> allow null elements.
-+ * Attempting to add a null key or value to the map will raise a <code>NullPointerException</code>.
-+ * <p/>
-+ * This implementation is not synchronized.
-+ * You can use {@link java.util.Collections#synchronizedMap} to
-+ * provide synchronized access to a <code>ReferenceIdentityMap</code>.
-+ * Remember that synchronization will not stop the garbage collecter removing entries.
-+ * <p/>
-+ * All the available iterators can be reset back to the start by casting to
-+ * <code>ResettableIterator</code> and calling <code>reset()</code>.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @see java.lang.ref.Reference
-+ * @since Commons Collections 3.0 (previously in main package v2.1)
-+ */
-+public class ReferenceIdentityMap <K,V> extends AbstractReferenceMap<K, V> implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -1266190134568365852L;
-+
-+    /**
-+     * Constructs a new <code>ReferenceIdentityMap</code> that will
-+     * use hard references to keys and soft references to values.
-+     */
-+    public ReferenceIdentityMap() {
-+        super(HARD, SOFT, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, false);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceIdentityMap</code> that will
-+     * use the specified types of references.
-+     *
-+     * @param keyType   the type of reference to use for keys;
-+     *                  must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType the type of reference to use for values;
-+     *                  must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     */
-+    public ReferenceIdentityMap(int keyType, int valueType) {
-+        super(keyType, valueType, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, false);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceIdentityMap</code> that will
-+     * use the specified types of references.
-+     *
-+     * @param keyType     the type of reference to use for keys;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType   the type of reference to use for values;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param purgeValues should the value be automatically purged when the
-+     *                    key is garbage collected
-+     */
-+    public ReferenceIdentityMap(int keyType, int valueType, boolean purgeValues) {
-+        super(keyType, valueType, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, purgeValues);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceIdentityMap</code> with the
-+     * specified reference types, load factor and initial capacity.
-+     *
-+     * @param keyType    the type of reference to use for keys;
-+     *                   must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType  the type of reference to use for values;
-+     *                   must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param capacity   the initial capacity for the map
-+     * @param loadFactor the load factor for the map
-+     */
-+    public ReferenceIdentityMap(int keyType, int valueType, int capacity, float loadFactor) {
-+        super(keyType, valueType, capacity, loadFactor, false);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceIdentityMap</code> with the
-+     * specified reference types, load factor and initial capacity.
-+     *
-+     * @param keyType     the type of reference to use for keys;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType   the type of reference to use for values;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param capacity    the initial capacity for the map
-+     * @param loadFactor  the load factor for the map
-+     * @param purgeValues should the value be automatically purged when the
-+     *                    key is garbage collected
-+     */
-+    public ReferenceIdentityMap(int keyType, int valueType, int capacity, float loadFactor, boolean purgeValues) {
-+        super(keyType, valueType, capacity, loadFactor, purgeValues);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the hash code for the key specified.
-+     * <p/>
-+     * This implementation uses the identity hash code.
-+     *
-+     * @param key the key to get a hash code for
-+     * @return the hash code
-+     */
-+    protected int hash(Object key) {
-+        return System.identityHashCode(key);
-+    }
-+
-+    /**
-+     * Gets the hash code for a MapEntry.
-+     * <p/>
-+     * This implementation uses the identity hash code.
-+     *
-+     * @param key   the key to get a hash code for, may be null
-+     * @param value the value to get a hash code for, may be null
-+     * @return the hash code, as per the MapEntry specification
-+     */
-+    protected int hashEntry(Object key, Object value) {
-+        return System.identityHashCode(key) ^ System.identityHashCode(value);
-+    }
-+
-+    /**
-+     * Compares two keys for equals.
-+     * <p/>
-+     * This implementation converts the key from the entry to a real reference
-+     * before comparison and uses <code>==</code>.
-+     *
-+     * @param key1 the first key to compare passed in from outside
-+     * @param key2 the second key extracted from the entry via <code>entry.key</code>
-+     * @return true if equal by identity
-+     */
-+    protected boolean isEqualKey(Object key1, Object key2) {
-+        // GenericsNote: I am disabled this line because of the new way that reference maps work, the getKey() method dereferences them for us.
-+        //key2 = (keyType > HARD ? ((Reference) key2).get() : key2);
-+        return (key1 == key2);
-+    }
-+
-+    /**
-+     * Compares two values for equals.
-+     * <p/>
-+     * This implementation uses <code>==</code>.
-+     *
-+     * @param value1 the first value to compare passed in from outside
-+     * @param value2 the second value extracted from the entry via <code>getValue()</code>
-+     * @return true if equal by identity
-+     */
-+    protected boolean isEqualValue(Object value1, Object value2) {
-+        return (value1 == value2);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/ReferenceMap.java
-@@ -0,0 +1,162 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+
-+/**
-+ * A <code>Map</code> implementation that allows mappings to be
-+ * removed by the garbage collector.
-+ * <p/>
-+ * When you construct a <code>ReferenceMap</code>, you can specify what kind
-+ * of references are used to store the map's keys and values.
-+ * If non-hard references are used, then the garbage collector can remove
-+ * mappings if a key or value becomes unreachable, or if the JVM's memory is
-+ * running low. For information on how the different reference types behave,
-+ * see {@link java.lang.ref.Reference}.
-+ * <p/>
-+ * Different types of references can be specified for keys and values.
-+ * The keys can be configured to be weak but the values hard,
-+ * in which case this class will behave like a
-+ * <a href="http://java.sun.com/j2se/1.4/docs/api/java/util/WeakHashMap.html">
-+ * <code>WeakHashMap</code></a>. However, you can also specify hard keys and
-+ * weak values, or any other combination. The default constructor uses
-+ * hard keys and soft values, providing a memory-sensitive cache.
-+ * <p/>
-+ * This map is similar to
-+ * {@link org.apache.commons.collections15.map.ReferenceIdentityMap ReferenceIdentityMap}.
-+ * It differs in that keys and values in this class are compared using <code>equals()</code>.
-+ * <p/>
-+ * This {@link java.util.Map} implementation does <i>not</i> allow null elements.
-+ * Attempting to add a null key or value to the map will raise a <code>NullPointerException</code>.
-+ * <p/>
-+ * This implementation is not synchronized.
-+ * You can use {@link java.util.Collections#synchronizedMap} to
-+ * provide synchronized access to a <code>ReferenceMap</code>.
-+ * Remember that synchronization will not stop the garbage collecter removing entries.
-+ * <p/>
-+ * All the available iterators can be reset back to the start by casting to
-+ * <code>ResettableIterator</code> and calling <code>reset()</code>.
-+ * <p/>
-+ * NOTE: As from Commons Collections 3.1 this map extends <code>AbstractReferenceMap</code>
-+ * (previously it extended AbstractMap). As a result, the implementation is now
-+ * extensible and provides a <code>MapIterator</code>.
-+ *
-+ * @author Paul Jack
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @see java.lang.ref.Reference
-+ * @since Commons Collections 3.0 (previously in main package v2.1)
-+ */
-+public class ReferenceMap <K,V> extends AbstractReferenceMap<K, V> implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 1555089888138299607L;
-+
-+    /**
-+     * Constructs a new <code>ReferenceMap</code> that will
-+     * use hard references to keys and soft references to values.
-+     */
-+    public ReferenceMap() {
-+        super(HARD, SOFT, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, false);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceMap</code> that will
-+     * use the specified types of references.
-+     *
-+     * @param keyType   the type of reference to use for keys;
-+     *                  must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType the type of reference to use for values;
-+     *                  must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     */
-+    public ReferenceMap(int keyType, int valueType) {
-+        super(keyType, valueType, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, false);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceMap</code> that will
-+     * use the specified types of references.
-+     *
-+     * @param keyType     the type of reference to use for keys;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType   the type of reference to use for values;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param purgeValues should the value be automatically purged when the
-+     *                    key is garbage collected
-+     */
-+    public ReferenceMap(int keyType, int valueType, boolean purgeValues) {
-+        super(keyType, valueType, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, purgeValues);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceMap</code> with the
-+     * specified reference types, load factor and initial
-+     * capacity.
-+     *
-+     * @param keyType    the type of reference to use for keys;
-+     *                   must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType  the type of reference to use for values;
-+     *                   must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param capacity   the initial capacity for the map
-+     * @param loadFactor the load factor for the map
-+     */
-+    public ReferenceMap(int keyType, int valueType, int capacity, float loadFactor) {
-+        super(keyType, valueType, capacity, loadFactor, false);
-+    }
-+
-+    /**
-+     * Constructs a new <code>ReferenceMap</code> with the
-+     * specified reference types, load factor and initial
-+     * capacity.
-+     *
-+     * @param keyType     the type of reference to use for keys;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param valueType   the type of reference to use for values;
-+     *                    must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
-+     * @param capacity    the initial capacity for the map
-+     * @param loadFactor  the load factor for the map
-+     * @param purgeValues should the value be automatically purged when the
-+     *                    key is garbage collected
-+     */
-+    public ReferenceMap(int keyType, int valueType, int capacity, float loadFactor, boolean purgeValues) {
-+        super(keyType, valueType, capacity, loadFactor, purgeValues);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        doWriteObject(out);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        doReadObject(in);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/SingletonMap.java
-@@ -0,0 +1,583 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.*;
-+import org.apache.commons.collections15.iterators.SingletonIterator;
-+import org.apache.commons.collections15.keyvalue.TiedMapEntry;
-+
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * A <code>Map</code> implementation that holds a single item and is fixed size.
-+ * <p/>
-+ * The single key/value pair is specified at creation.
-+ * The map is fixed size so any action that would change the size is disallowed.
-+ * However, the <code>put</code> or <code>setValue</code> methods can <i>change</i>
-+ * the value associated with the key.
-+ * <p/>
-+ * If trying to remove or clear the map, an UnsupportedOperationException is thrown.
-+ * If trying to put a new mapping into the map, an  IllegalArgumentException is thrown.
-+ * The put method will only suceed if the key specified is the same as the
-+ * singleton key.
-+ * <p/>
-+ * The key and value can be obtained by:
-+ * <ul>
-+ * <li>normal Map methods and views
-+ * <li>the <code>MapIterator</code>, see {@link #mapIterator()}
-+ * <li>the <code>KeyValue</code> interface (just cast - no object creation)
-+ * </ul>
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.1
-+ */
-+public class SingletonMap <K,V> implements OrderedMap<K, V>, BoundedMap<K, V>, KeyValue<K, V>, Serializable, Cloneable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -8931271118676803261L;
-+
-+    /**
-+     * Singleton key
-+     */
-+    private final K key;
-+    /**
-+     * Singleton value
-+     */
-+    private V value;
-+
-+    /**
-+     * Constructor that creates a map of <code>null</code> to <code>null</code>.
-+     */
-+    public SingletonMap() {
-+        super();
-+        this.key = null;
-+    }
-+
-+    /**
-+     * Constructor specifying the key and value.
-+     *
-+     * @param key   the key to use
-+     * @param value the value to use
-+     */
-+    public SingletonMap(K key, V value) {
-+        super();
-+        this.key = key;
-+        this.value = value;
-+    }
-+
-+    /**
-+     * Constructor specifying the key and value as a <code>KeyValue</code>.
-+     *
-+     * @param keyValue the key value pair to use
-+     */
-+    public SingletonMap(KeyValue<K, V> keyValue) {
-+        super();
-+        this.key = keyValue.getKey();
-+        this.value = keyValue.getValue();
-+    }
-+
-+    /**
-+     * Constructor specifying the key and value as a <code>MapEntry</code>.
-+     *
-+     * @param entry the key value pair to use
-+     */
-+    public SingletonMap(Map.Entry<K, V> entry) {
-+        super();
-+        this.key = entry.getKey();
-+        this.value = entry.getValue();
-+    }
-+
-+    /**
-+     * Constructor copying elements from another map.
-+     *
-+     * @param map the map to copy, must be size 1
-+     * @throws NullPointerException     if the map is null
-+     * @throws IllegalArgumentException if the size is not 1
-+     */
-+    public SingletonMap(Map<? extends K, ? extends V> map) {
-+        super();
-+        if (map.size() != 1) {
-+            throw new IllegalArgumentException("The map size must be 1");
-+        }
-+        Map.Entry<? extends K, ? extends V> entry = map.entrySet().iterator().next();
-+        this.key = entry.getKey();
-+        this.value = entry.getValue();
-+    }
-+
-+    // KeyValue
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the key.
-+     *
-+     * @return the key
-+     */
-+    public K getKey() {
-+        return key;
-+    }
-+
-+    /**
-+     * Gets the value.
-+     *
-+     * @return the value
-+     */
-+    public V getValue() {
-+        return value;
-+    }
-+
-+    /**
-+     * Sets the value.
-+     *
-+     * @param value the new value to set
-+     * @return the old value
-+     */
-+    public V setValue(V value) {
-+        V old = this.value;
-+        this.value = value;
-+        return old;
-+    }
-+
-+    // BoundedMap
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Is the map currently full, always true.
-+     *
-+     * @return true always
-+     */
-+    public boolean isFull() {
-+        return true;
-+    }
-+
-+    /**
-+     * Gets the maximum size of the map, always 1.
-+     *
-+     * @return 1 always
-+     */
-+    public int maxSize() {
-+        return 1;
-+    }
-+
-+    // Map
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the value mapped to the key specified.
-+     *
-+     * @param key the key
-+     * @return the mapped value, null if no match
-+     */
-+    public V get(Object key) {
-+        if (isEqualKey(key)) {
-+            return value;
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Gets the size of the map, always 1.
-+     *
-+     * @return the size of 1
-+     */
-+    public int size() {
-+        return 1;
-+    }
-+
-+    /**
-+     * Checks whether the map is currently empty, which it never is.
-+     *
-+     * @return false always
-+     */
-+    public boolean isEmpty() {
-+        return false;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Checks whether the map contains the specified key.
-+     *
-+     * @param key the key to search for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsKey(Object key) {
-+        return (isEqualKey(key));
-+    }
-+
-+    /**
-+     * Checks whether the map contains the specified value.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the key
-+     */
-+    public boolean containsValue(Object value) {
-+        return (isEqualValue(value));
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Puts a key-value mapping into this map where the key must match the existing key.
-+     * <p/>
-+     * An IllegalArgumentException is thrown if the key does not match as the map
-+     * is fixed size.
-+     *
-+     * @param key   the key to set, must be the key of the map
-+     * @param value the value to set
-+     * @return the value previously mapped to this key, null if none
-+     * @throws IllegalArgumentException if the key does not match
-+     */
-+    public V put(K key, V value) {
-+        if (isEqualKey(key)) {
-+            return setValue(value);
-+        }
-+        throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size singleton");
-+    }
-+
-+    /**
-+     * Puts the values from the specified map into this map.
-+     * <p/>
-+     * The map must be of size 0 or size 1.
-+     * If it is size 1, the key must match the key of this map otherwise an
-+     * IllegalArgumentException is thrown.
-+     *
-+     * @param map the map to add, must be size 0 or 1, and the key must match
-+     * @throws NullPointerException     if the map is null
-+     * @throws IllegalArgumentException if the key does not match
-+     */
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        switch (map.size()) {
-+            case 0:
-+                return;
-+
-+            case 1:
-+                Map.Entry<? extends K, ? extends V> entry = map.entrySet().iterator().next();
-+                put(entry.getKey(), entry.getValue());
-+                return;
-+
-+            default:
-+                throw new IllegalArgumentException("The map size must be 0 or 1");
-+        }
-+    }
-+
-+    /**
-+     * Unsupported operation.
-+     *
-+     * @param key the mapping to remove
-+     * @return the value mapped to the removed key, null if key not in map
-+     * @throws UnsupportedOperationException always
-+     */
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    /**
-+     * Unsupported operation.
-+     */
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the entrySet view of the map.
-+     * Changes made via <code>setValue</code> affect this map.
-+     * To simply iterate through the entries, use {@link #mapIterator()}.
-+     *
-+     * @return the entrySet view
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Map.Entry<K, V> entry = new TiedMapEntry<K, V>(this, getKey());
-+        return Collections.singleton(entry);
-+    }
-+
-+    /**
-+     * Gets the unmodifiable keySet view of the map.
-+     * Changes made to the view affect this map.
-+     * To simply iterate through the keys, use {@link #mapIterator()}.
-+     *
-+     * @return the keySet view
-+     */
-+    public Set<K> keySet() {
-+        return Collections.singleton(key);
-+    }
-+
-+    /**
-+     * Gets the unmodifiable values view of the map.
-+     * Changes made to the view affect this map.
-+     * To simply iterate through the values, use {@link #mapIterator()}.
-+     *
-+     * @return the values view
-+     */
-+    public Collection<V> values() {
-+        return new SingletonValues(this);
-+    }
-+
-+    /**
-+     * Gets an iterator over the map.
-+     * Changes made to the iterator using <code>setValue</code> affect this map.
-+     * The <code>remove</code> method is unsupported.
-+     * <p/>
-+     * A MapIterator returns the keys in the map. It also provides convenient
-+     * methods to get the key and value, and set the value.
-+     * It avoids the need to create an entrySet/keySet/values object.
-+     * It also avoids creating the Map Entry object.
-+     *
-+     * @return the map iterator
-+     */
-+    public MapIterator<K, V> mapIterator() {
-+        return new SingletonMapIterator<K, V>(this);
-+    }
-+
-+    // OrderedMap
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Obtains an <code>OrderedMapIterator</code> over the map.
-+     * <p/>
-+     * A ordered map iterator is an efficient way of iterating over maps
-+     * in both directions.
-+     *
-+     * @return an ordered map iterator
-+     */
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        return new SingletonMapIterator<K, V>(this);
-+    }
-+
-+    /**
-+     * Gets the first (and only) key in the map.
-+     *
-+     * @return the key
-+     */
-+    public K firstKey() {
-+        return getKey();
-+    }
-+
-+    /**
-+     * Gets the last (and only) key in the map.
-+     *
-+     * @return the key
-+     */
-+    public K lastKey() {
-+        return getKey();
-+    }
-+
-+    /**
-+     * Gets the next key after the key specified, always null.
-+     *
-+     * @param key the next key
-+     * @return null always
-+     */
-+    public K nextKey(K key) {
-+        return null;
-+    }
-+
-+    /**
-+     * Gets the previous key before the key specified, always null.
-+     *
-+     * @param key the next key
-+     * @return null always
-+     */
-+    public K previousKey(K key) {
-+        return null;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Compares the specified key to the stored key.
-+     *
-+     * @param key the key to compare
-+     * @return true if equal
-+     */
-+    protected boolean isEqualKey(Object key) {
-+        return (key == null ? getKey() == null : key.equals(getKey()));
-+    }
-+
-+    /**
-+     * Compares the specified value to the stored value.
-+     *
-+     * @param value the value to compare
-+     * @return true if equal
-+     */
-+    protected boolean isEqualValue(Object value) {
-+        return (value == null ? getValue() == null : value.equals(getValue()));
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * SingletonMapIterator.
-+     */
-+    static class SingletonMapIterator <K,V> implements OrderedMapIterator<K, V>, ResettableIterator<K> {
-+        private final SingletonMap<K, V> parent;
-+        private boolean hasNext = true;
-+        private boolean canGetSet = false;
-+
-+        SingletonMapIterator(SingletonMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public boolean hasNext() {
-+            return hasNext;
-+        }
-+
-+        public K next() {
-+            if (hasNext == false) {
-+                throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
-+            }
-+            hasNext = false;
-+            canGetSet = true;
-+            return parent.getKey();
-+        }
-+
-+        public boolean hasPrevious() {
-+            return (hasNext == false);
-+        }
-+
-+        public K previous() {
-+            if (hasNext == true) {
-+                throw new NoSuchElementException(AbstractHashedMap.NO_PREVIOUS_ENTRY);
-+            }
-+            hasNext = true;
-+            return parent.getKey();
-+        }
-+
-+        public void remove() {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public K getKey() {
-+            if (canGetSet == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
-+            }
-+            return parent.getKey();
-+        }
-+
-+        public V getValue() {
-+            if (canGetSet == false) {
-+                throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
-+            }
-+            return parent.getValue();
-+        }
-+
-+        public V setValue(V value) {
-+            if (canGetSet == false) {
-+                throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
-+            }
-+            return parent.setValue(value);
-+        }
-+
-+        public void reset() {
-+            hasNext = true;
-+        }
-+
-+        public String toString() {
-+            if (hasNext) {
-+                return "Iterator[]";
-+            } else {
-+                return "Iterator[" + getKey() + "=" + getValue() + "]";
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Values implementation for the SingletonMap.
-+     * This class is needed as values is a view that must update as the map updates.
-+     */
-+    static class SingletonValues <K,V> extends AbstractSet<V> implements Serializable {
-+        private static final long serialVersionUID = -3689524741863047872L;
-+        private final SingletonMap<K, V> parent;
-+
-+        SingletonValues(SingletonMap<K, V> parent) {
-+            super();
-+            this.parent = parent;
-+        }
-+
-+        public int size() {
-+            return 1;
-+        }
-+
-+        public boolean isEmpty() {
-+            return false;
-+        }
-+
-+        public boolean contains(Object object) {
-+            return parent.containsValue(object);
-+        }
-+
-+        public void clear() {
-+            throw new UnsupportedOperationException();
-+        }
-+
-+        public Iterator<V> iterator() {
-+            return new SingletonIterator<V>(parent.getValue(), false);
-+        }
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map without cloning the key or value.
-+     *
-+     * @return a shallow clone
-+     */
-+    public Object clone() {
-+        try {
-+            SingletonMap cloned = (SingletonMap) super.clone();
-+            return cloned;
-+        } catch (CloneNotSupportedException ex) {
-+            throw new InternalError();
-+        }
-+    }
-+
-+    /**
-+     * Compares this map with another.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof Map == false) {
-+            return false;
-+        }
-+        Map other = (Map) obj;
-+        if (other.size() != 1) {
-+            return false;
-+        }
-+        Map.Entry entry = (Map.Entry) other.entrySet().iterator().next();
-+        return isEqualKey(entry.getKey()) && isEqualValue(entry.getValue());
-+    }
-+
-+    /**
-+     * Gets the standard Map hashCode.
-+     *
-+     * @return the hash code defined in the Map interface
-+     */
-+    public int hashCode() {
-+        return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode());
-+    }
-+
-+    /**
-+     * Gets the map as a String.
-+     *
-+     * @return a string version of the map
-+     */
-+    public String toString() {
-+        return new StringBuffer(128).append('{').append(getKey()).append('=').append(getValue()).append('}').toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/StaticBucketMap.java
-@@ -0,0 +1,702 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2002-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.KeyValue;
-+
-+import java.util.*;
-+
-+/**
-+ * A StaticBucketMap is an efficient, thread-safe implementation of
-+ * <code>java.util.Map</code> that performs well in in a highly
-+ * thread-contentious environment.  The map supports very efficient
-+ * {@link #get(Object) get}, {@link #put(Object,Object) put},
-+ * {@link #remove(Object) remove} and {@link #containsKey(Object) containsKey}
-+ * operations, assuming (approximate) uniform hashing and
-+ * that the number of entries does not exceed the number of buckets.  If the
-+ * number of entries exceeds the number of buckets or if the hash codes of the
-+ * objects are not uniformly distributed, these operations have a worst case
-+ * scenario that is proportional to the number of elements in the map
-+ * (<i>O(n)</i>).<p>
-+ * <p/>
-+ * Each bucket in the hash table has its own monitor, so two threads can
-+ * safely operate on the map at the same time, often without incurring any
-+ * monitor contention.  This means that you don't have to wrap instances
-+ * of this class with {@link java.util.Collections#synchronizedMap(Map)};
-+ * instances are already thread-safe.  Unfortunately, however, this means
-+ * that this map implementation behaves in ways you may find disconcerting.
-+ * Bulk operations, such as {@link #putAll(Map) putAll} or the
-+ * {@link Collection#retainAll(Collection) retainAll} operation in collection
-+ * views, are <i>not</i> atomic.  If two threads are simultaneously
-+ * executing
-+ * <p/>
-+ * <pre>
-+ *   staticBucketMapInstance.putAll(map);
-+ * </pre>
-+ * <p/>
-+ * and
-+ * <p/>
-+ * <pre>
-+ *   staticBucketMapInstance.entrySet().removeAll(map.entrySet());
-+ * </pre>
-+ * <p/>
-+ * then the results are generally random.  Those two statement could cancel
-+ * each other out, leaving <code>staticBucketMapInstance</code> essentially
-+ * unchanged, or they could leave some random subset of <code>map</code> in
-+ * <code>staticBucketMapInstance</code>.<p>
-+ * <p/>
-+ * Also, much like an encyclopedia, the results of {@link #size()} and
-+ * {@link #isEmpty()} are out-of-date as soon as they are produced.<p>
-+ * <p/>
-+ * The iterators returned by the collection views of this class are <i>not</i>
-+ * fail-fast.  They will <i>never</i> raise a
-+ * {@link java.util.ConcurrentModificationException}.  Keys and values
-+ * added to the map after the iterator is created do not necessarily appear
-+ * during iteration.  Similarly, the iterator does not necessarily fail to
-+ * return keys and values that were removed after the iterator was created.<p>
-+ * <p/>
-+ * Finally, unlike {@link java.util.HashMap}-style implementations, this
-+ * class <i>never</i> rehashes the map.  The number of buckets is fixed
-+ * at construction time and never altered.  Performance may degrade if
-+ * you do not allocate enough buckets upfront.<p>
-+ * <p/>
-+ * The {@link #atomic(Runnable)} method is provided to allow atomic iterations
-+ * and bulk operations; however, overuse of {@link #atomic(Runnable) atomic}
-+ * will basically result in a map that's slower than an ordinary synchronized
-+ * {@link java.util.HashMap}.
-+ * <p/>
-+ * Use this class if you do not require reliable bulk operations and
-+ * iterations, or if you can make your own guarantees about how bulk
-+ * operations will affect the map.<p>
-+ *
-+ * @author Berin Loritsch
-+ * @author Gerhard Froehlich
-+ * @author Michael A. Smith
-+ * @author Paul Jack
-+ * @author Leo Sutic
-+ * @author Matt Hall, John Watkinson, Janek Bogucki
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0 (previously in main package v2.1)
-+ */
-+public final class StaticBucketMap <K,V> implements Map<K, V> {
-+
-+    /**
-+     * The default number of buckets to use
-+     */
-+    private static final int DEFAULT_BUCKETS = 255;
-+    /**
-+     * The array of buckets, where the actual data is held
-+     */
-+    private Node<K, V>[] buckets;
-+    /**
-+     * The matching array of locks
-+     */
-+    private Lock[] locks;
-+
-+    /**
-+     * Initializes the map with the default number of buckets (255).
-+     */
-+    public StaticBucketMap() {
-+        this(DEFAULT_BUCKETS);
-+    }
-+
-+    /**
-+     * Initializes the map with a specified number of buckets.  The number
-+     * of buckets is never below 17, and is always an odd number (StaticBucketMap
-+     * ensures this). The number of buckets is inversely proportional to the
-+     * chances for thread contention.  The fewer buckets, the more chances for
-+     * thread contention.  The more buckets the fewer chances for thread
-+     * contention.
-+     *
-+     * @param numBuckets the number of buckets for this map
-+     */
-+    public StaticBucketMap(int numBuckets) {
-+        int size = Math.max(17, numBuckets);
-+
-+        // Ensure that bucketSize is never a power of 2 (to ensure maximal distribution)
-+        if (size % 2 == 0) {
-+            size--;
-+        }
-+
-+        buckets = new Node[size];
-+        locks = new Lock[size];
-+
-+        for (int i = 0; i < size; i++) {
-+            locks[i] = new Lock();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Determine the exact hash entry for the key.  The hash algorithm
-+     * is rather simplistic, but it does the job:
-+     * <p/>
-+     * <pre>
-+     *   He = |Hk mod n|
-+     * </pre>
-+     * <p/>
-+     * <p/>
-+     * He is the entry's hashCode, Hk is the key's hashCode, and n is
-+     * the number of buckets.
-+     * </p>
-+     */
-+    private final int getHash(Object key) {
-+        if (key == null) {
-+            return 0;
-+        }
-+        int hash = key.hashCode();
-+        hash += ~(hash << 15);
-+        hash ^= (hash >>> 10);
-+        hash += (hash << 3);
-+        hash ^= (hash >>> 6);
-+        hash += ~(hash << 11);
-+        hash ^= (hash >>> 16);
-+        hash %= buckets.length;
-+        return (hash < 0) ? hash * -1 : hash;
-+    }
-+
-+    /**
-+     * Gets the current size of the map.
-+     * The value is computed fresh each time the method is called.
-+     *
-+     * @return the current size
-+     */
-+    public int size() {
-+        int cnt = 0;
-+
-+        for (int i = 0; i < buckets.length; i++) {
-+            cnt += locks[i].size;
-+        }
-+        return cnt;
-+    }
-+
-+    /**
-+     * Checks if the size is currently zero.
-+     *
-+     * @return true if empty
-+     */
-+    public boolean isEmpty() {
-+        return (size() == 0);
-+    }
-+
-+    /**
-+     * Gets the value associated with the key.
-+     *
-+     * @param key the key to retrieve
-+     * @return the associated value
-+     */
-+    public V get(final Object key) {
-+        int hash = getHash(key);
-+
-+        synchronized (locks[hash]) {
-+            Node<K, V> n = buckets[hash];
-+
-+            while (n != null) {
-+                if (n.key == key || (n.key != null && n.key.equals(key))) {
-+                    return n.value;
-+                }
-+
-+                n = n.next;
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Checks if the map contains the specified key.
-+     *
-+     * @param key the key to check
-+     * @return true if found
-+     */
-+    public boolean containsKey(final Object key) {
-+        int hash = getHash(key);
-+
-+        synchronized (locks[hash]) {
-+            Node n = buckets[hash];
-+
-+            while (n != null) {
-+                if (n.key == null || (n.key != null && n.key.equals(key))) {
-+                    return true;
-+                }
-+
-+                n = n.next;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Checks if the map contains the specified value.
-+     *
-+     * @param value the value to check
-+     * @return true if found
-+     */
-+    public boolean containsValue(final Object value) {
-+        for (int i = 0; i < buckets.length; i++) {
-+            synchronized (locks[i]) {
-+                Node n = buckets[i];
-+
-+                while (n != null) {
-+                    if (n.value == value || (n.value != null && n.value.equals(value))) {
-+                        return true;
-+                    }
-+
-+                    n = n.next;
-+                }
-+            }
-+        }
-+        return false;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Puts a new key value mapping into the map.
-+     *
-+     * @param key   the key to use
-+     * @param value the value to use
-+     * @return the previous mapping for the key
-+     */
-+    public V put(final K key, final V value) {
-+        int hash = getHash(key);
-+
-+        synchronized (locks[hash]) {
-+            Node<K, V> n = buckets[hash];
-+
-+            if (n == null) {
-+                n = new Node<K, V>();
-+                n.key = key;
-+                n.value = value;
-+                buckets[hash] = n;
-+                locks[hash].size++;
-+                return null;
-+            }
-+
-+            // Set n to the last node in the linked list.  Check each key along the way
-+            //  If the key is found, then change the value of that node and return
-+            //  the old value.
-+            for (Node<K, V> next = n; next != null; next = next.next) {
-+                n = next;
-+
-+                if (n.key == key || (n.key != null && n.key.equals(key))) {
-+                    V returnVal = n.value;
-+                    n.value = value;
-+                    return returnVal;
-+                }
-+            }
-+
-+            // The key was not found in the current list of nodes, add it to the end
-+            //  in a new node.
-+            Node<K, V> newNode = new Node<K, V>();
-+            newNode.key = key;
-+            newNode.value = value;
-+            n.next = newNode;
-+            locks[hash].size++;
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Removes the specified key from the map.
-+     *
-+     * @param key the key to remove
-+     * @return the previous value at this key
-+     */
-+    public V remove(Object key) {
-+        int hash = getHash(key);
-+
-+        synchronized (locks[hash]) {
-+            Node<K, V> n = buckets[hash];
-+            Node<K, V> prev = null;
-+
-+            while (n != null) {
-+                if (n.key == key || (n.key != null && n.key.equals(key))) {
-+                    // Remove this node from the linked list of nodes.
-+                    if (null == prev) {
-+                        // This node was the head, set the next node to be the new head.
-+                        buckets[hash] = n.next;
-+                    } else {
-+                        // Set the next node of the previous node to be the node after this one.
-+                        prev.next = n.next;
-+                    }
-+                    locks[hash].size--;
-+                    return n.value;
-+                }
-+
-+                prev = n;
-+                n = n.next;
-+            }
-+        }
-+        return null;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the key set.
-+     *
-+     * @return the key set
-+     */
-+    public Set<K> keySet() {
-+        return new KeySet();
-+    }
-+
-+    /**
-+     * Gets the values.
-+     *
-+     * @return the values
-+     */
-+    public Collection<V> values() {
-+        return new Values();
-+    }
-+
-+    /**
-+     * Gets the entry set.
-+     *
-+     * @return the entry set
-+     */
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        return new EntrySet();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Puts all the entries from the specified map into this map.
-+     * This operation is <b>not atomic</b> and may have undesired effects.
-+     *
-+     * @param map the map of entries to add
-+     */
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        Iterator i = map.keySet().iterator();
-+
-+        while (i.hasNext()) {
-+            K key = (K) i.next();
-+            put(key, (V) map.get(key));
-+        }
-+    }
-+
-+    /**
-+     * Clears the map of all entries.
-+     */
-+    public void clear() {
-+        for (int i = 0; i < buckets.length; i++) {
-+            Lock lock = locks[i];
-+            synchronized (lock) {
-+                buckets[i] = null;
-+                lock.size = 0;
-+            }
-+        }
-+    }
-+
-+    /**
-+     * Compares this map to another, as per the Map specification.
-+     *
-+     * @param obj the object to compare to
-+     * @return true if equal
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj == this) {
-+            return true;
-+        }
-+        if (obj instanceof Map == false) {
-+            return false;
-+        }
-+        Map other = (Map) obj;
-+        return entrySet().equals(other.entrySet());
-+    }
-+
-+    /**
-+     * Gets the hash code, as per the Map specification.
-+     *
-+     * @return the hash code
-+     */
-+    public int hashCode() {
-+        int hashCode = 0;
-+
-+        for (int i = 0; i < buckets.length; i++) {
-+            synchronized (locks[i]) {
-+                Node n = buckets[i];
-+
-+                while (n != null) {
-+                    hashCode += n.hashCode();
-+                    n = n.next;
-+                }
-+            }
-+        }
-+        return hashCode;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * The Map.Entry for the StaticBucketMap.
-+     */
-+    private static final class Node <K,V> implements Map.Entry<K, V>, KeyValue<K, V> {
-+        protected K key;
-+        protected V value;
-+        protected Node<K, V> next;
-+
-+        public K getKey() {
-+            return key;
-+        }
-+
-+        public V getValue() {
-+            return value;
-+        }
-+
-+        public int hashCode() {
-+            return ((key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()));
-+        }
-+
-+        public boolean equals(Object obj) {
-+            if (obj == this) {
-+                return true;
-+            }
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+
-+            Map.Entry e2 = (Map.Entry) obj;
-+            return ((key == null ? e2.getKey() == null : key.equals(e2.getKey())) && (value == null ? e2.getValue() == null : value.equals(e2.getValue())));
-+        }
-+
-+        public V setValue(V obj) {
-+            V retVal = value;
-+            value = obj;
-+            return retVal;
-+        }
-+    }
-+
-+
-+    /**
-+     * The lock object, which also includes a count of the nodes in this lock.
-+     */
-+    private final static class Lock {
-+        public int size;
-+    }
-+
-+    private class EntryIterator extends IteratorBase implements Iterator<Map.Entry<K, V>> {
-+
-+        public Entry<K, V> next() {
-+            return superNext();
-+        }
-+
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    private class IteratorBase {
-+
-+        private ArrayList<Map.Entry<K, V>> current = new ArrayList<Map.Entry<K, V>>();
-+        private int bucket;
-+        private Map.Entry<K, V> last;
-+
-+
-+        public boolean hasNext() {
-+            if (current.size() > 0) return true;
-+            while (bucket < buckets.length) {
-+                synchronized (locks[bucket]) {
-+                    Node<K, V> n = buckets[bucket];
-+                    while (n != null) {
-+                        current.add(n);
-+                        n = n.next;
-+                    }
-+                    bucket++;
-+                    if (current.size() > 0) return true;
-+                }
-+            }
-+            return false;
-+        }
-+
-+        protected Map.Entry<K, V> nextEntry() {
-+            if (!hasNext()) throw new NoSuchElementException();
-+            last = current.remove(current.size() - 1);
-+            return last;
-+        }
-+
-+        public Map.Entry<K, V> superNext() {
-+            return nextEntry();
-+        }
-+
-+        public void remove() {
-+            if (last == null) throw new IllegalStateException();
-+            StaticBucketMap.this.remove(last.getKey());
-+            last = null;
-+        }
-+
-+    }
-+
-+    private class ValueIterator extends IteratorBase implements Iterator<V> {
-+
-+        public V next() {
-+            return nextEntry().getValue();
-+        }
-+
-+    }
-+
-+    private class KeyIterator extends IteratorBase implements Iterator<K> {
-+
-+        public K next() {
-+            return nextEntry().getKey();
-+        }
-+
-+    }
-+
-+    private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
-+
-+        public int size() {
-+            return StaticBucketMap.this.size();
-+        }
-+
-+        public void clear() {
-+            StaticBucketMap.this.clear();
-+        }
-+
-+        public Iterator<Map.Entry<K, V>> iterator() {
-+            return new EntryIterator();
-+        }
-+
-+        public boolean contains(Object obj) {
-+            Map.Entry entry = (Map.Entry) obj;
-+            int hash = getHash(entry.getKey());
-+            synchronized (locks[hash]) {
-+                for (Node n = buckets[hash]; n != null; n = n.next) {
-+                    if (n.equals(entry)) return true;
-+                }
-+            }
-+            return false;
-+        }
-+
-+        public boolean remove(Object obj) {
-+            if (obj instanceof Map.Entry == false) {
-+                return false;
-+            }
-+            Map.Entry entry = (Map.Entry) obj;
-+            int hash = getHash(entry.getKey());
-+            synchronized (locks[hash]) {
-+                for (Node n = buckets[hash]; n != null; n = n.next) {
-+                    if (n.equals(entry)) {
-+                        StaticBucketMap.this.remove(n.getKey());
-+                        return true;
-+                    }
-+                }
-+            }
-+            return false;
-+        }
-+
-+    }
-+
-+
-+    private class KeySet extends AbstractSet<K> {
-+
-+        public int size() {
-+            return StaticBucketMap.this.size();
-+        }
-+
-+        public void clear() {
-+            StaticBucketMap.this.clear();
-+        }
-+
-+        public Iterator<K> iterator() {
-+            return new KeyIterator();
-+        }
-+
-+        public boolean contains(Object obj) {
-+            return StaticBucketMap.this.containsKey(obj);
-+        }
-+
-+        public boolean remove(Object obj) {
-+            int hash = getHash(obj);
-+            synchronized (locks[hash]) {
-+                for (Node n = buckets[hash]; n != null; n = n.next) {
-+                    Object k = n.getKey();
-+                    if ((k == obj) || ((k != null) && k.equals(obj))) {
-+                        StaticBucketMap.this.remove(k);
-+                        return true;
-+                    }
-+                }
-+            }
-+            return false;
-+
-+        }
-+
-+    }
-+
-+
-+    private class Values extends AbstractCollection<V> {
-+
-+        public int size() {
-+            return StaticBucketMap.this.size();
-+        }
-+
-+        public void clear() {
-+            StaticBucketMap.this.clear();
-+        }
-+
-+        public Iterator<V> iterator() {
-+            return new ValueIterator();
-+        }
-+
-+    }
-+
-+
-+    /**
-+     * Prevents any operations from occurring on this map while the
-+     * given {@link Runnable} executes.  This method can be used, for
-+     * instance, to execute a bulk operation atomically:
-+     * <p/>
-+     * <pre>
-+     *    staticBucketMapInstance.atomic(new Runnable() {
-+     *        public void run() {
-+     *            staticBucketMapInstance.putAll(map);
-+     *        }
-+     *    });
-+     *  </pre>
-+     * <p/>
-+     * It can also be used if you need a reliable iterator:
-+     * <p/>
-+     * <pre>
-+     *    staticBucketMapInstance.atomic(new Runnable() {
-+     *        public void run() {
-+     *            Iterator iterator = staticBucketMapInstance.iterator();
-+     *            while (iterator.hasNext()) {
-+     *                foo(iterator.next();
-+     *            }
-+     *        }
-+     *    });
-+     *  </pre>
-+     * <p/>
-+     * <b>Implementation note:</b> This method requires a lot of time
-+     * and a ton of stack space.  Essentially a recursive algorithm is used
-+     * to enter each bucket's monitor.  If you have twenty thousand buckets
-+     * in your map, then the recursive method will be invoked twenty thousand
-+     * times.  You have been warned.
-+     *
-+     * @param r the code to execute atomically
-+     */
-+    public void atomic(Runnable r) {
-+        if (r == null) throw new NullPointerException();
-+        atomic(r, 0);
-+    }
-+
-+    private void atomic(Runnable r, int bucket) {
-+        if (bucket >= buckets.length) {
-+            r.run();
-+            return;
-+        }
-+        synchronized (locks[bucket]) {
-+            atomic(r, bucket + 1);
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/TransformedMap.java
-@@ -0,0 +1,200 @@
-+// TODO: Not yet converted, deprecated (by me).
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Iterator;
-+import java.util.Map;
-+
-+/**
-+ * Decorates another <code>Map</code> to transform objects that are added.
-+ * <p/>
-+ * The Map put methods and Map.Entry setValue method are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Map contract.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedMap extends AbstractInputCheckedMapDecorator implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 7023152376788900464L;
-+
-+    /**
-+     * The transformer to use for the key
-+     */
-+    protected final Transformer keyTransformer;
-+    /**
-+     * The transformer to use for the value
-+     */
-+    protected final Transformer valueTransformer;
-+
-+    /**
-+     * Factory method to create a transforming map.
-+     * <p/>
-+     * If there are any elements already in the map being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param map              the map to decorate, must not be null
-+     * @param keyTransformer   the transformer to use for key conversion, null means no conversion
-+     * @param valueTransformer the transformer to use for value conversion, null means no conversion
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
-+        return new TransformedMap(map, keyTransformer, valueTransformer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param map              the map to decorate, must not be null
-+     * @param keyTransformer   the transformer to use for key conversion, null means no conversion
-+     * @param valueTransformer the transformer to use for value conversion, null means no conversion
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
-+        super(map);
-+        this.keyTransformer = keyTransformer;
-+        this.valueTransformer = valueTransformer;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Transforms a key.
-+     * <p/>
-+     * The transformer itself may throw an exception if necessary.
-+     *
-+     * @param object the object to transform
-+     * @throws the transformed object
-+     */
-+    protected Object transformKey(Object object) {
-+        if (keyTransformer == null) {
-+            return object;
-+        }
-+        return keyTransformer.transform(object);
-+    }
-+
-+    /**
-+     * Transforms a value.
-+     * <p/>
-+     * The transformer itself may throw an exception if necessary.
-+     *
-+     * @param object the object to transform
-+     * @throws the transformed object
-+     */
-+    protected Object transformValue(Object object) {
-+        if (valueTransformer == null) {
-+            return object;
-+        }
-+        return valueTransformer.transform(object);
-+    }
-+
-+    /**
-+     * Transforms a map.
-+     * <p/>
-+     * The transformer itself may throw an exception if necessary.
-+     *
-+     * @param map the map to transform
-+     * @throws the transformed object
-+     */
-+    protected Map transformMap(Map map) {
-+        Map result = new LinkedMap(map.size());
-+        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry entry = (Map.Entry) it.next();
-+            result.put(transformKey(entry.getKey()), transformValue(entry.getValue()));
-+        }
-+        return result;
-+    }
-+
-+    /**
-+     * Override to transform the value when using <code>setValue</code>.
-+     *
-+     * @param value the value to transform
-+     * @return the transformed value
-+     * @since Commons Collections 3.1
-+     */
-+    protected Object checkSetValue(Object value) {
-+        return valueTransformer.transform(value);
-+    }
-+
-+    /**
-+     * Override to only return true when there is a value transformer.
-+     *
-+     * @return true if a value transformer is in use
-+     * @since Commons Collections 3.1
-+     */
-+    protected boolean isSetValueChecking() {
-+        return (valueTransformer != null);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Object put(Object key, Object value) {
-+        key = transformKey(key);
-+        value = transformValue(value);
-+        return getMap().put(key, value);
-+    }
-+
-+    public void putAll(Map mapToCopy) {
-+        mapToCopy = transformMap(mapToCopy);
-+        getMap().putAll(mapToCopy);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/TransformedSortedMap.java
-@@ -0,0 +1,116 @@
-+// TODO: Not yet converted, deprecated (by me).
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.Comparator;
-+import java.util.SortedMap;
-+
-+/**
-+ * Decorates another <code>SortedMap </code> to transform objects that are added.
-+ * <p/>
-+ * The Map put methods and Map.Entry setValue method are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Map contract.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedSortedMap extends TransformedMap implements SortedMap {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -8751771676410385778L;
-+
-+    /**
-+     * Factory method to create a transforming sorted map.
-+     * <p/>
-+     * If there are any elements already in the map being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param map              the map to decorate, must not be null
-+     * @param keyTransformer   the predicate to validate the keys, null means no transformation
-+     * @param valueTransformer the predicate to validate to values, null means no transformation
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    public static SortedMap decorate(SortedMap map, Transformer keyTransformer, Transformer valueTransformer) {
-+        return new TransformedSortedMap(map, keyTransformer, valueTransformer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the collection being decorated, they
-+     * are NOT transformed.</p>
-+     *
-+     * @param map              the map to decorate, must not be null
-+     * @param keyTransformer   the predicate to validate the keys, null means no transformation
-+     * @param valueTransformer the predicate to validate to values, null means no transformation
-+     * @throws IllegalArgumentException if the map is null
-+     */
-+    protected TransformedSortedMap(SortedMap map, Transformer keyTransformer, Transformer valueTransformer) {
-+        super(map, keyTransformer, valueTransformer);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the map being decorated.
-+     *
-+     * @return the decorated map
-+     */
-+    protected SortedMap getSortedMap() {
-+        return (SortedMap) map;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Object firstKey() {
-+        return getSortedMap().firstKey();
-+    }
-+
-+    public Object lastKey() {
-+        return getSortedMap().lastKey();
-+    }
-+
-+    public Comparator comparator() {
-+        return getSortedMap().comparator();
-+    }
-+
-+    public SortedMap subMap(Object fromKey, Object toKey) {
-+        SortedMap map = getSortedMap().subMap(fromKey, toKey);
-+        return new TransformedSortedMap(map, keyTransformer, valueTransformer);
-+    }
-+
-+    public SortedMap headMap(Object toKey) {
-+        SortedMap map = getSortedMap().headMap(toKey);
-+        return new TransformedSortedMap(map, keyTransformer, valueTransformer);
-+    }
-+
-+    public SortedMap tailMap(Object fromKey) {
-+        SortedMap map = getSortedMap().tailMap(fromKey);
-+        return new TransformedSortedMap(map, keyTransformer, valueTransformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/TypedMap.java
-@@ -0,0 +1,63 @@
-+// TODO: Not yet converted, deprecated (by me).
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+import java.util.Map;
-+
-+/**
-+ * Decorates another <code>Map</code> to validate that elements added
-+ * are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * The returned implementation is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ * @deprecated no longer needed with Java generics.
-+ */
-+public class TypedMap {
-+
-+    /**
-+     * Factory method to create a typed map.
-+     * <p/>
-+     * If there are any elements already in the map being decorated, they
-+     * are validated.
-+     *
-+     * @param map       the map to decorate, must not be null
-+     * @param keyType   the type to allow as keys, must not be null
-+     * @param valueType the type to allow as values, must not be null
-+     * @throws IllegalArgumentException if list or type is null
-+     * @throws IllegalArgumentException if the list contains invalid elements
-+     */
-+    public static Map decorate(Map map, Class keyType, Class valueType) {
-+        return new PredicatedMap(map, InstanceofPredicate.getInstance(keyType), InstanceofPredicate.getInstance(valueType));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedMap() {
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/TypedSortedMap.java
-@@ -0,0 +1,63 @@
-+// TODO: Not yet converted, deprecated (by me).
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+import java.util.SortedMap;
-+
-+/**
-+ * Decorates another <code>SortedMap</code> to validate that elements added
-+ * are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * The returned implementation is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ * @deprecated no longer needed with Java generics.
-+ */
-+public class TypedSortedMap {
-+
-+    /**
-+     * Factory method to create a typed sorted map.
-+     * <p/>
-+     * If there are any elements already in the map being decorated, they
-+     * are validated.
-+     *
-+     * @param map       the map to decorate, must not be null
-+     * @param keyType   the type to allow as keys, must not be null
-+     * @param valueType the type to allow as values, must not be null
-+     * @throws IllegalArgumentException if list or type is null
-+     * @throws IllegalArgumentException if the list contains invalid elements
-+     */
-+    public static SortedMap decorate(SortedMap map, Class keyType, Class valueType) {
-+        return new PredicatedSortedMap(map, InstanceofPredicate.getInstance(keyType), InstanceofPredicate.getInstance(valueType));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedSortedMap() {
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/UnmodifiableEntrySet.java
-@@ -0,0 +1,161 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.AbstractIteratorDecorator;
-+import org.apache.commons.collections15.keyvalue.AbstractMapEntryDecorator;
-+import org.apache.commons.collections15.set.AbstractSetDecorator;
-+
-+import java.lang.reflect.Array;
-+import java.util.*;
-+
-+/**
-+ * Decorates a map entry <code>Set</code> to ensure it can't be altered.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableEntrySet <K,V> extends AbstractSetDecorator<Map.Entry<K, V>> implements Unmodifiable {
-+
-+    /**
-+     * Factory method to create an unmodifiable set of Map Entry objects.
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    public static <K,V> Set<Map.Entry<K, V>> decorate(Set<Map.Entry<K, V>> set) {
-+        if (set instanceof Unmodifiable) {
-+            return set;
-+        }
-+        return new UnmodifiableEntrySet<K, V>(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    private UnmodifiableEntrySet(Set<Map.Entry<K, V>> set) {
-+        super(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public boolean add(Map.Entry<K, V> object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends Map.Entry<K, V>> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<Map.Entry<K, V>> iterator() {
-+        return new UnmodifiableEntrySetIterator<K, V>(collection.iterator());
-+    }
-+
-+    public Object[] toArray() {
-+        Object[] array = collection.toArray();
-+        for (int i = 0; i < array.length; i++) {
-+            array[i] = new UnmodifiableEntry((Map.Entry) array[i]);
-+        }
-+        return array;
-+    }
-+
-+    public <T> T[] toArray(T array[]) {
-+        T[] result = array;
-+        if (array.length > 0) {
-+            // we must create a new array to handle multi-threaded situations
-+            // where another thread could access data before we decorate it
-+            result = (T[]) Array.newInstance(array.getClass().getComponentType(), 0);
-+        }
-+        result = collection.toArray(result);
-+        Collection<UnmodifiableEntry<K, V>> newCollection = new ArrayList<UnmodifiableEntry<K, V>>();
-+        for (int i = 0; i < result.length; i++) {
-+            //            result[i] = new UnmodifiableEntry<K,V>((Map.Entry) result[i]);
-+            newCollection.add(new UnmodifiableEntry<K, V>((Map.Entry) result[i]));
-+        }
-+        result = newCollection.toArray(result);
-+
-+        // check to see if result should be returned straight
-+        if (result.length > array.length) {
-+            return result;
-+        }
-+
-+        // copy back into input array to fulfil the method contract
-+        System.arraycopy(result, 0, array, 0, result.length);
-+        if (array.length > result.length) {
-+            array[result.length] = null;
-+        }
-+        return array;
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implementation of an entry set iterator.
-+     */
-+    final static class UnmodifiableEntrySetIterator <K,V> extends AbstractIteratorDecorator<Map.Entry<K, V>> {
-+
-+        protected UnmodifiableEntrySetIterator(Iterator<Map.Entry<K, V>> iterator) {
-+            super(iterator);
-+        }
-+
-+        public Map.Entry<K, V> next() {
-+            Map.Entry entry = (Map.Entry) iterator.next();
-+            return new UnmodifiableEntry<K, V>(entry);
-+        }
-+
-+        public void remove() {
-+            throw new UnsupportedOperationException();
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Implementation of a map entry that is unmodifiable.
-+     */
-+    final static class UnmodifiableEntry <K,V> extends AbstractMapEntryDecorator<K, V> {
-+
-+        protected UnmodifiableEntry(Map.Entry<K, V> entry) {
-+            super(entry);
-+        }
-+
-+        public V setValue(V obj) {
-+            throw new UnsupportedOperationException();
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/UnmodifiableMap.java
-@@ -0,0 +1,143 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.IterableMap;
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.collection.UnmodifiableCollection;
-+import org.apache.commons.collections15.iterators.EntrySetMapIterator;
-+import org.apache.commons.collections15.iterators.UnmodifiableMapIterator;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Map</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableMap <K,V> extends AbstractMapDecorator<K, V> implements IterableMap<K, V>, Unmodifiable, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 2737023427269031941L;
-+
-+    /**
-+     * Factory method to create an unmodifiable map.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> Map<K, V> decorate(Map<K, V> map) {
-+        if (map instanceof Unmodifiable) {
-+            return map;
-+        }
-+        return new UnmodifiableMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    private UnmodifiableMap(Map<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V put(K key, V value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public MapIterator<K, V> mapIterator() {
-+        if (map instanceof IterableMap) {
-+            MapIterator<K, V> it = ((IterableMap<K, V>) map).mapIterator();
-+            return UnmodifiableMapIterator.decorate(it);
-+        } else {
-+            MapIterator<K, V> it = new EntrySetMapIterator<K, V>(map);
-+            return UnmodifiableMapIterator.decorate(it);
-+        }
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = super.entrySet();
-+        return UnmodifiableEntrySet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = super.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Collection<V> values() {
-+        Collection<V> coll = super.values();
-+        return UnmodifiableCollection.decorate(coll);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/UnmodifiableOrderedMap.java
-@@ -0,0 +1,144 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.MapIterator;
-+import org.apache.commons.collections15.OrderedMap;
-+import org.apache.commons.collections15.OrderedMapIterator;
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.collection.UnmodifiableCollection;
-+import org.apache.commons.collections15.iterators.UnmodifiableMapIterator;
-+import org.apache.commons.collections15.iterators.UnmodifiableOrderedMapIterator;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>OrderedMap</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableOrderedMap <K,V> extends AbstractOrderedMapDecorator<K, V> implements Unmodifiable, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 8136428161720526266L;
-+
-+    /**
-+     * Factory method to create an unmodifiable sorted map.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> OrderedMap<K, V> decorate(OrderedMap<K, V> map) {
-+        if (map instanceof Unmodifiable) {
-+            return map;
-+        }
-+        return new UnmodifiableOrderedMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    private UnmodifiableOrderedMap(OrderedMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map<K, V>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public MapIterator<K, V> mapIterator() {
-+        MapIterator<K, V> it = getOrderedMap().mapIterator();
-+        return UnmodifiableMapIterator.decorate(it);
-+    }
-+
-+    public OrderedMapIterator<K, V> orderedMapIterator() {
-+        OrderedMapIterator<K, V> it = getOrderedMap().orderedMapIterator();
-+        return UnmodifiableOrderedMapIterator.decorate(it);
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V put(K key, V value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = super.entrySet();
-+        return UnmodifiableEntrySet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = super.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Collection<V> values() {
-+        Collection<V> coll = super.values();
-+        return UnmodifiableCollection.decorate(coll);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/UnmodifiableSortedMap.java
-@@ -0,0 +1,155 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.map;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.collection.UnmodifiableCollection;
-+import org.apache.commons.collections15.set.UnmodifiableSet;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * Decorates another <code>SortedMap</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:32 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableSortedMap <K,V> extends AbstractSortedMapDecorator<K, V> implements Unmodifiable, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 5805344239827376360L;
-+
-+    /**
-+     * Factory method to create an unmodifiable sorted map.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> SortedMap<K, V> decorate(SortedMap<K, V> map) {
-+        if (map instanceof Unmodifiable) {
-+            return map;
-+        }
-+        return new UnmodifiableSortedMap<K, V>(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    private UnmodifiableSortedMap(SortedMap<K, V> map) {
-+        super(map);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the map out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     * @since Commons Collections 3.1
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(map);
-+    }
-+
-+    /**
-+     * Read the map in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     * @since Commons Collections 3.1
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        map = (Map<K, V>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V put(K key, V value) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public V remove(Object key) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public Set<Map.Entry<K, V>> entrySet() {
-+        Set<Map.Entry<K, V>> set = super.entrySet();
-+        return UnmodifiableEntrySet.decorate(set);
-+    }
-+
-+    public Set<K> keySet() {
-+        Set<K> set = super.keySet();
-+        return UnmodifiableSet.decorate(set);
-+    }
-+
-+    public Collection<V> values() {
-+        Collection<V> coll = super.values();
-+        return UnmodifiableCollection.decorate(coll);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public K firstKey() {
-+        return getSortedMap().firstKey();
-+    }
-+
-+    public K lastKey() {
-+        return getSortedMap().lastKey();
-+    }
-+
-+    public Comparator<? super K> comparator() {
-+        return getSortedMap().comparator();
-+    }
-+
-+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
-+        SortedMap<K, V> map = getSortedMap().subMap(fromKey, toKey);
-+        return new UnmodifiableSortedMap<K, V>(map);
-+    }
-+
-+    public SortedMap<K, V> headMap(K toKey) {
-+        SortedMap<K, V> map = getSortedMap().headMap(toKey);
-+        return new UnmodifiableSortedMap<K, V>(map);
-+    }
-+
-+    public SortedMap<K, V> tailMap(K fromKey) {
-+        SortedMap<K, V> map = getSortedMap().tailMap(fromKey);
-+        return new UnmodifiableSortedMap<K, V>(map);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/map/package.html
-@@ -0,0 +1,54 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:32 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the 
-+{@link java.util.Map Map},
-+{@link org.apache.commons.collections.IterableMap IterableMap},
-+{@link org.apache.commons.collections.OrderedMap OrderedMap} and
-+{@link java.util.SortedMap SortedMap} interfaces.
-+A Map provides a lookup from a key to a value.
-+A number of implementations also support the new MapIterator interface that enables
-+simple iteration of map keys and values.
-+<p>
-+The following implementations are provided:
-+<ul>
-+<li>CaseInsensitiveMap - map that compares keys in a case insensitive way
-+<li>CompositeMap - map that combines multiple maps into a single view
-+<li>HashedMap - general purpose HashMap replacement supporting MapIterator
-+<li>IdentityMap - map that uses == for comparison instead of equals()
-+<li>Flat3Map - designed for good performance at size 3 or less
-+<li>LinkedMap - a hash map that maintains insertion order, supporting OrderedMapIterator
-+<li>MultiKeyMap - map that provides special methods for using more than one key to access the value
-+<li>ReferenceMap - allows the garbage collector to collect keys and values using equals() for comparison
-+<li>ReferenceIdentityMap - allows the garbage collector to collect keys and values using == for comparison
-+<li>SingletonMap - a fully featured map to hold one key-value pair
-+<li>StaticBucketMap - internally synchronized and designed for thread-contentious environments
-+</ul>
-+<p>
-+The following decorators are provided:
-+<ul>
-+<li>Unmodifiable - ensures the collection cannot be altered
-+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
-+<li>Typed - ensures that only elements that are of a specific type can be added
-+<li>Transformed - transforms each element added
-+<li>FixedSize - ensures that the size of the map cannot change
-+<li>Lazy - creates objects in the map on demand
-+<li>ListOrdered - ensures that insertion order is retained
-+</ul>
-+</pre>
-+</BODY>
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/multimap/MultiHashMap.java
-@@ -0,0 +1,524 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2001-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.multimap;
-+
-+import org.apache.commons.collections15.iterators.EmptyIterator;
-+import org.apache.commons.collections15.MultiMap;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.Serializable;
-+import java.util.*;
-+
-+/**
-+ * <code>MultiHashMap</code> is the default implementation of the
-+ * {@link org.apache.commons.collections15.MultiMap MultiMap} interface.
-+ * <p/>
-+ * A <code>MultiMap</code> is like a Map, but with slightly different semantics.
-+ * Putting a value into the map will add the value to a Collection at that key.
-+ * Getting a value will return a Collection, holding all the values put to that key.
-+ * <p/>
-+ * This implementation uses an <code>ArrayList</code> as the collection.
-+ * The internal storage list is made available without cloning via the
-+ * <code>get(Object)</code> and <code>entrySet()</code> methods.
-+ * The implementation returns <code>null</code> when there are no values mapped to a key.
-+ * <p/>
-+ * For example:
-+ * <pre>
-+ * Number key = new Integer(5);
-+ * MultiMap<Number,String> mhm = new MultiHashMap<Number,String>();
-+ * mhm.put(key, "A");
-+ * mhm.put(key, "B");
-+ * mhm.put(key, "C");
-+ * Collection<String> coll = mhm.get(key);</pre>
-+ * <p/>
-+ * <code>list</code> will be a list containing "A", "B", "C".
-+ *
-+ * @author Christopher Berry
-+ * @author James Strachan
-+ * @author Steve Downey
-+ * @author Stephen Colebourne
-+ * @author Julien Buret
-+ * @author Matt Hall, John Watkinson, Serhiy Yevtushenko
-+ * @version $Revision: 1.2 $ $Date: 2006/06/08 15:19:55 $
-+ * @since Commons Collections 2.0
-+ */
-+public class MultiHashMap<K,V> implements MultiMap<K,V>, Serializable, Cloneable {
-+
-+    // backed values collection
-+    private transient Collection values = null;
-+
-+    // compatibility with commons-collection releases 2.0/2.1
-+    private static final long serialVersionUID = 1943563828307035349L;
-+
-+    private HashMap<K,Collection<V>> internalMap;
-+
-+    /**
-+     * Constructor.
-+     */
-+    public MultiHashMap() {
-+        internalMap = new HashMap<K, Collection<V>>();
-+    }
-+
-+    /**
-+     * Constructor.
-+     *
-+     * @param initialCapacity the initial map capacity
-+     */
-+    public MultiHashMap(int initialCapacity) {
-+        internalMap = new HashMap<K, Collection<V>>(initialCapacity);
-+    }
-+
-+    /**
-+     * Constructor.
-+     *
-+     * @param initialCapacity the initial map capacity
-+     * @param loadFactor      the amount 0.0-1.0 at which to resize the map
-+     */
-+    public MultiHashMap(int initialCapacity, float loadFactor) {
-+        internalMap = new HashMap<K, Collection<V>>(initialCapacity, loadFactor);
-+    }
-+
-+    /**
-+     * Constructor that copies the input map creating an independent copy.
-+     * <p/>
-+     * The values are not cloned.
-+     * <p/>
-+     *
-+     * @param mapToCopy a Map to copy
-+     */
-+    public MultiHashMap(Map<K, V> mapToCopy) {
-+        // be careful of JDK 1.3 vs 1.4 differences
-+        internalMap = new HashMap<K, Collection<V>>((int) (mapToCopy.size() * 1.4f));
-+        putAll(mapToCopy);
-+    }
-+
-+    /**
-+     * Constructor that copies the input MultiMap creating an independent copy.
-+     * <p/>
-+     * Each internal collection is also cloned.
-+     * <p/>
-+     * NOTE: From Commons Collections 3.1 this method correctly copies a MultiMap
-+     * to form a truly independent new map.
-+     *
-+     * @param mapToCopy a Map to copy
-+     */
-+    public MultiHashMap(MultiMap<K,V> mapToCopy) {
-+        internalMap = new HashMap<K, Collection<V>>((int) (mapToCopy.size() * 1.4f));
-+        for (Iterator<Map.Entry<K,Collection<V>>> it = mapToCopy.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<K,Collection<V>> entry = it.next();
-+            Collection<V> coll = entry.getValue();
-+            Collection<V> newColl = createCollection(coll);
-+            internalMap.put(entry.getKey(), newColl);
-+        }
-+
-+    }
-+
-+    /**
-+     * Read the object during deserialization.
-+     */
-+    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
-+        // This method is needed because the 1.2/1.3 Java deserialisation called
-+        // put and thus messed up that method
-+
-+        // default read object
-+        s.defaultReadObject();
-+
-+        // problem only with jvm <1.4
-+        String version = "1.2";
-+        try {
-+            version = System.getProperty("java.version");
-+        } catch (SecurityException ex) {
-+            // ignore and treat as 1.2/1.3
-+        }
-+
-+        if (version.startsWith("1.2") || version.startsWith("1.3")) {
-+            for (Iterator<Map.Entry<K,Collection<V>>> iterator = entrySet().iterator(); iterator.hasNext();) {
-+                Map.Entry<K,Collection<V>> entry = iterator.next();
-+                // put has created a extra collection level, remove it
-+                internalMap.put(entry.getKey(), entry.getValue());
-+            }
-+        }
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets the total size of the map by counting all the values.
-+     *
-+     * @return the total size of the map counting all values
-+     * @since Commons Collections 3.1
-+     */
-+    public int totalSize() {
-+        int total = 0;
-+        Collection<Collection<V>> values = internalMap.values();
-+        for (Iterator<Collection<V>> it = values.iterator(); it.hasNext();) {
-+            Collection<V> coll = it.next();
-+            total += coll.size();
-+        }
-+        return total;
-+    }
-+
-+    /**
-+     * Gets the collection mapped to the specified key.
-+     * This method is a convenience method to typecast the result of <code>get(key)</code>.
-+     *
-+     * @param key the key to retrieve
-+     * @return the collection mapped to the key, null if no mapping
-+     * @since Commons Collections 3.1
-+     */
-+    public Collection<V> getCollection(Object key) {
-+        return internalMap.get(key);
-+    }
-+
-+    /**
-+     * Gets the size of the collection mapped to the specified key.
-+     *
-+     * @param key the key to get size for
-+     * @return the size of the collection at the key, zero if key not in map
-+     * @since Commons Collections 3.1
-+     */
-+    public int size(Object key) {
-+        Collection<V> coll = getCollection(key);
-+        if (coll == null) {
-+            return 0;
-+        }
-+        return coll.size();
-+    }
-+
-+    /**
-+     * Gets an iterator for the collection mapped to the specified key.
-+     *
-+     * @param key the key to get an iterator for
-+     * @return the iterator of the collection at the key, empty iterator if key not in map
-+     * @since Commons Collections 3.1
-+     */
-+    public Iterator<V> iterator(Object key) {
-+        Collection<V> coll = getCollection(key);
-+        if (coll == null) {
-+            return EmptyIterator.INSTANCE;
-+        }
-+        return coll.iterator();
-+    }
-+
-+    /**
-+     * Adds the value to the collection associated with the specified key.
-+     * <p/>
-+     * Unlike a normal <code>Map</code> the previous value is not replaced.
-+     * Instead the new value is added to the collection stored against the key.
-+     *
-+     * @param key   the key to store against
-+     * @param value the value to add to the collection at the key
-+     * @return the value added if the map changed and null if the map did not change
-+     */
-+    public V put(K key, V value) {
-+        // NOTE:: put is called during deserialization in JDK < 1.4 !!!!!!
-+        //        so we must have a readObject()
-+        Collection<V> coll = getCollection(key);
-+        if (coll == null) {
-+            coll = createCollection(null);
-+            internalMap.put(key, coll);
-+        }
-+        boolean results = coll.add(value);
-+        return results ? value : null;
-+    }
-+
-+    /**
-+     * Adds a collection of values to the collection associated with the specified key.
-+     *
-+     * @param key    the key to store against
-+     * @param values the values to add to the collection at the key, null ignored
-+     * @return true if this map changed
-+     * @since Commons Collections 3.1
-+     */
-+    public boolean putAll(K key, Collection<? extends V> values) {
-+        if (values == null || values.size() == 0) {
-+            return false;
-+        }
-+        Collection<V> coll = getCollection(key);
-+        if (coll == null) {
-+            coll = createCollection(values);
-+            if (coll.size() == 0) {
-+                return false;
-+            }
-+            internalMap.put(key, coll);
-+            return true;
-+        } else {
-+            return coll.addAll(values);
-+        }
-+    }
-+
-+    /**
-+     * Checks whether the map contains the value specified.
-+     * <p/>
-+     * This checks all collections15 against all keys for the value, and thus could be slow.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the value
-+     */
-+    public boolean containsValue(Object value) {
-+        Set<Map.Entry<K,Collection<V>>> pairs = internalMap.entrySet();
-+
-+        if (pairs == null) {
-+            return false;
-+        }
-+        Iterator<Map.Entry<K,Collection<V>>> pairsIterator = pairs.iterator();
-+        while (pairsIterator.hasNext()) {
-+            Map.Entry<K,Collection<V>> keyValuePair = pairsIterator.next();
-+            Collection<V> coll = keyValuePair.getValue();
-+            if (coll.contains(value)) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * Checks whether the collection at the specified key contains the value.
-+     *
-+     * @param value the value to search for
-+     * @return true if the map contains the value
-+     * @since Commons Collections 3.1
-+     */
-+    public boolean containsValue(Object key, Object value) {
-+        Collection<V> coll = getCollection(key);
-+        if (coll == null) {
-+            return false;
-+        }
-+        return coll.contains(value);
-+    }
-+
-+    /**
-+     * Removes a specific value from map.
-+     * <p/>
-+     * The item is removed from the collection mapped to the specified key.
-+     * Other values attached to that key are unaffected.
-+     * <p/>
-+     * If the last value for a key is removed, <code>null</code> will be returned
-+     * from a subsequant <code>get(key)</code>.
-+     *
-+     * @param key  the key to remove from
-+     * @param item the value to remove
-+     * @return the value removed (which was passed in), null if nothing removed
-+     */
-+    public V remove(Object key, Object item) {
-+        Collection valuesForKey = getCollection(key);
-+        if (valuesForKey == null) {
-+            return null;
-+        }
-+        valuesForKey.remove(item);
-+
-+        // remove the list if it is now empty
-+        // (saves space, and allows equals to work)
-+        if (valuesForKey.isEmpty()) {
-+            remove(key);
-+        }
-+        return (V)item;
-+    }
-+
-+    /**
-+     * Clear the map.
-+     * <p/>
-+     * This clears each collection in the map, and so may be slow.
-+     */
-+    public void clear() {
-+        // For gc, clear each list in the map
-+        Set<Map.Entry<K,Collection<V>>> pairs = internalMap.entrySet();
-+        Iterator<Map.Entry<K,Collection<V>>> pairsIterator = pairs.iterator();
-+        while (pairsIterator.hasNext()) {
-+            Map.Entry<K,Collection<V>> keyValuePair = pairsIterator.next();
-+            Collection<V> coll = keyValuePair.getValue();
-+            coll.clear();
-+        }
-+        internalMap.clear();
-+    }
-+
-+    public int size() {
-+        return internalMap.size();
-+    }
-+
-+    public Collection<V> get(Object key) {
-+        return internalMap.get(key);
-+    }
-+
-+    public Collection<V> remove(Object key) {
-+        return internalMap.remove(key);
-+    }
-+
-+    public boolean isEmpty() {
-+        return internalMap.isEmpty();
-+    }
-+
-+    public boolean containsKey(Object key) {
-+        return internalMap.containsKey(key);
-+    }
-+
-+    public void putAll(Map<? extends K, ? extends V> map) {
-+        for (K key : map.keySet()) {
-+            put(key, map.get(key));
-+        }
-+    }
-+
-+    public void putAll(MultiMap<? extends K, ? extends V> map) {
-+        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<? extends K, Collection<? extends V>> entry = (Map.Entry<? extends K, Collection<? extends V>>) it.next();
-+            for (V v : entry.getValue()) {
-+                put(entry.getKey(), v);
-+            }
-+        }
-+    }
-+
-+    public Set<K> keySet() {
-+        return internalMap.keySet();
-+    }
-+
-+    public Set<Map.Entry<K, Collection<V>>> entrySet() {
-+        return internalMap.entrySet();
-+    }
-+
-+    public Map<K, Collection<V>> map() {
-+        return internalMap;
-+    }
-+
-+    /**
-+     * Gets a collection containing all the values in the map.
-+     * <p/>
-+     * This returns a collection containing the combination of values from all keys.
-+     *
-+     * @return a collection view of the values contained in this map
-+     */
-+    public Collection<V> values() {
-+        Collection vs = values;
-+        return vs != null ? vs : (values = new Values<V>());
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Inner class to view the elements.
-+     */
-+    private class Values<T> extends AbstractCollection<V> {
-+
-+        public Iterator<V> iterator() {
-+            return new ValueIterator<V>();
-+        }
-+
-+        public int size() {
-+            int compt = 0;
-+            Iterator it = iterator();
-+            while (it.hasNext()) {
-+                it.next();
-+                compt++;
-+            }
-+            return compt;
-+        }
-+
-+        public void clear() {
-+            MultiHashMap.this.clear();
-+        }
-+
-+    }
-+
-+    /**
-+     * Inner iterator to view the elements.
-+     */
-+    private class ValueIterator<T> implements Iterator<V> {
-+        private Iterator<Collection<V>> backedIterator;
-+        private Iterator<V> tempIterator;
-+
-+        private ValueIterator() {
-+            backedIterator = internalMap.values().iterator();
-+        }
-+
-+        private boolean searchNextIterator() {
-+            while (tempIterator == null || tempIterator.hasNext() == false) {
-+                if (backedIterator.hasNext() == false) {
-+                    return false;
-+                }
-+                tempIterator = backedIterator.next().iterator();
-+            }
-+            return true;
-+        }
-+
-+        public boolean hasNext() {
-+            return searchNextIterator();
-+        }
-+
-+        public V next() {
-+            if (searchNextIterator() == false) {
-+                throw new NoSuchElementException();
-+            }
-+            return tempIterator.next();
-+        }
-+
-+        public void remove() {
-+            if (tempIterator == null) {
-+                throw new IllegalStateException();
-+            }
-+            tempIterator.remove();
-+        }
-+
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Clones the map creating an independent copy.
-+     * <p/>
-+     * The clone will shallow clone the collections15 as well as the map.
-+     *
-+     * @return the cloned map
-+     */
-+    public Object clone() {
-+        MultiHashMap<K,V> cloned = new MultiHashMap<K, V>();
-+        for (Iterator<Map.Entry<K,Collection<V>>> it = internalMap.entrySet().iterator(); it.hasNext();) {
-+            Map.Entry<K,Collection<V>> entry = it.next();
-+            for (V v : entry.getValue()) {
-+                cloned.put(entry.getKey(), v);
-+            }
-+        }
-+        return cloned;
-+    }
-+
-+    public boolean equals(Object obj) {
-+        if (obj instanceof MultiHashMap) {
-+            return internalMap.equals(((MultiHashMap)obj).map());
-+        } else return false;
-+    }
-+
-+    public int hashCode() {
-+        return internalMap.hashCode();
-+    }
-+
-+    /**
-+     * Creates a new instance of the map value Collection container.
-+     * <p/>
-+     * This method can be overridden to use your own collection type.
-+     *
-+     * @param coll the collection to copy, may be null
-+     * @return the new collection
-+     */
-+    protected Collection<V> createCollection(Collection<? extends V> coll) {
-+        if (coll == null) {
-+            return new ArrayList<V>();
-+        } else {
-+            return new ArrayList<V>(coll);
-+        }
-+    }
-+
-+    public String toString() {
-+        return internalMap.toString();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/overview.html
-@@ -0,0 +1,112 @@
-+<!-- $Id: overview.html,v 1.1 2005/10/11 17:05:19 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<body>
-+  <p>
-+     Commons-Collections contains implementations, enhancements and utilities
-+     that complement the Java Collections Framework.
-+  </p>
-+  <p>
-+     The Apache Jakarta Commons Collections Framework component adds a significant
-+     amount of enhancements to the standard JDK collections. These enhancements
-+     come in the form of new interfaces, new implementations and utility classes.
-+  </p>
-+  <p>
-+     See also the <code>java.util</code> package for the standard Java collections.
-+  </p>
-+     
-+  <h4>Main features</h4>
-+  <p>
-+     Commons-Collections defines a number of key interfaces:
-+  </p>
-+  <table border="1" cellspacing="0" cellpadding="3">
-+  <tr bgcolor="#CCCCFF" class="TableHeadingColor">
-+    <th>Interface</th><th>Description</th>
-+  </tr>
-+  <tr>
-+    <td>
-+      {@link org.apache.commons.collections.Bag}
-+    </td>
-+    <td valign="top">
-+      A new <code>Collection</code> subinterface that stores each object together
-+      with the number of occurances. Methods are provided to get the number of
-+      occurances, and to add and remove a certain number of that object.
-+    </td>
-+  </tr>
-+  <tr>
-+    <td>
-+      {@link org.apache.commons.collections.Buffer}
-+    </td>
-+    <td valign="top">
-+      A new <code>Collection</code> subinterface that allows objects to be removed
-+      in some well-defined order. Methods enable the next item to be peeked and removed.
-+    </td>
-+  </tr>
-+  <tr>
-+    <td>
-+      {@link org.apache.commons.collections.BidiMap}
-+    </td>
-+    <td valign="top">
-+      A new <code>Map</code> subinterface that allows lookup from key to value and
-+      from value to key with equal ease.
-+    </td>
-+  </tr>
-+  <tr>
-+    <td>
-+      {@link org.apache.commons.collections.OrderedMap}
-+    </td>
-+    <td valign="top">
-+      A new <code>Map</code> subinterface that is used when a map has an order, but is
-+      not sorted. Methods enable bidriectional iteration through the map.
-+    </td>
-+  </tr>
-+  <tr>
-+    <td>
-+      {@link org.apache.commons.collections.MapIterator}
-+    </td>
-+    <td valign="top">
-+      A new <code>Iterator</code> subinterface specially designed for maps. This iterator
-+      avoids the need for entrySet iteration of a map, and is simpler to use.
-+    </td>
-+  </tr>
-+  <tr>
-+    <td>
-+      {@link org.apache.commons.collections.ResettableIterator}
-+    </td>
-+    <td valign="top">
-+      A new <code>Iterator</code> subinterface that allows the iteration to be reset back
-+      to the start. Many iterators in this library have this functionality.
-+    </td>
-+  </tr>
-+  <tr>
-+    <td>
-+      {@link org.apache.commons.collections.Closure}<br />
-+      {@link org.apache.commons.collections.Predicate}<br />
-+      {@link org.apache.commons.collections.Transformer}<br />
-+      {@link org.apache.commons.collections.Factory}<br />
-+    </td>
-+    <td valign="top">
-+      A group of <i>functor</i> interfaces that provide plugin behaviour to various
-+      collections and utilities.
-+    </td>
-+  </tr>
-+  </table>
-+  <p>
-+     In addition to the interfaces, there are many implementations.
-+     Consult each subpackage for full details of these.
-+  </p>
-+     
-+</body>
-\ No newline at end of file
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/package.html
-@@ -0,0 +1,31 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:19 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<body>
-+<p>
-+This package contains the interfaces and utilities shared across all the subpackages of this component.
-+</p>
-+<p>
-+The following collection implementations are provided in the package:
-+<ul>
-+<li>ArrayStack - a non synchronized Stack that follows the same API as java util Stack
-+<li>BeanMap - a map that wraps a JavaBean, representing its properties as map keys and values
-+<li>ExtendedProperties - extends the Properties class to add extra functionality
-+<li>MultiHashMap - an map that stores multiple values against each key
-+</ul>
-+<p>
-+     
-+</body>
-\ No newline at end of file
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/AbstractSerializableSetDecorator.java
-@@ -0,0 +1,70 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Set;
-+
-+/**
-+ * Serializable subclass of AbstractSetDecorator.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @since Commons Collections 3.1
-+ */
-+public abstract class AbstractSerializableSetDecorator <E> extends AbstractSetDecorator<E> implements Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 1229469966212206107L;
-+
-+    /**
-+     * Constructor.
-+     */
-+    protected AbstractSerializableSetDecorator(Set<E> set) {
-+        super(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the set out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(collection);
-+    }
-+
-+    /**
-+     * Read the set in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        collection = (Collection<E>) in.readObject();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/AbstractSetDecorator.java
-@@ -0,0 +1,62 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.collection.AbstractCollectionDecorator;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Set</code> to provide additional behaviour.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated set.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractSetDecorator <E> extends AbstractCollectionDecorator<E> implements Set<E> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractSetDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    protected AbstractSetDecorator(Set<E> set) {
-+        super(set);
-+    }
-+
-+    /**
-+     * Gets the set being decorated.
-+     *
-+     * @return the decorated set
-+     */
-+    protected Set<E> getSet() {
-+        return (Set<E>) getCollection();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/AbstractSortedSetDecorator.java
-@@ -0,0 +1,87 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import java.util.Comparator;
-+import java.util.Set;
-+import java.util.SortedSet;
-+
-+/**
-+ * Decorates another <code>SortedSet</code> to provide additional behaviour.
-+ * <p/>
-+ * Methods are forwarded directly to the decorated set.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public abstract class AbstractSortedSetDecorator <E> extends AbstractSetDecorator<E> implements SortedSet<E> {
-+
-+    /**
-+     * Constructor only used in deserialization, do not use otherwise.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    protected AbstractSortedSetDecorator() {
-+        super();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    protected AbstractSortedSetDecorator(Set<E> set) {
-+        super(set);
-+    }
-+
-+    /**
-+     * Gets the sorted set being decorated.
-+     *
-+     * @return the decorated set
-+     */
-+    protected SortedSet<E> getSortedSet() {
-+        return (SortedSet<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedSet<E> subSet(E fromElement, E toElement) {
-+        return getSortedSet().subSet(fromElement, toElement);
-+    }
-+
-+    public SortedSet<E> headSet(E toElement) {
-+        return getSortedSet().headSet(toElement);
-+    }
-+
-+    public SortedSet<E> tailSet(E fromElement) {
-+        return getSortedSet().tailSet(fromElement);
-+    }
-+
-+    public E first() {
-+        return getSortedSet().first();
-+    }
-+
-+    public E last() {
-+        return getSortedSet().last();
-+    }
-+
-+    public Comparator<? super E> comparator() {
-+        return getSortedSet().comparator();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/CompositeSet.java
-@@ -0,0 +1,197 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.CollectionUtils;
-+import org.apache.commons.collections15.collection.CompositeCollection;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Set;
-+
-+/**
-+ * Decorates a set of other sets to provide a single unified view.
-+ * <p/>
-+ * Changes made to this set will actually be made on the decorated set.
-+ * Add and remove operations require the use of a pluggable strategy. If no
-+ * strategy is provided then add and remove are unsupported.
-+ *
-+ * @author Matt Hall, John Watkinson, Brian McCallister
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class CompositeSet <E> extends CompositeCollection<E> implements Set<E> {
-+    /**
-+     * Create an empty CompositeSet
-+     */
-+    public CompositeSet() {
-+        super();
-+    }
-+
-+    /**
-+     * Create a CompositeSet with just <code>set</code> composited
-+     *
-+     * @param set The initial set in the composite
-+     */
-+    public CompositeSet(Set<E> set) {
-+        super(set);
-+    }
-+
-+    /**
-+     * Create a composite set with sets as the initial set of composited Sets
-+     */
-+    public CompositeSet(Set<E>... sets) {
-+        super(sets);
-+    }
-+
-+    /**
-+     * Add a Set to this composite
-+     *
-+     * @param c Must implement Set
-+     * @throws IllegalArgumentException      if c does not implement java.util.Set
-+     *                                       or if a SetMutator is set, but fails to resolve a collision
-+     * @throws UnsupportedOperationException if there is no SetMutator set, or
-+     *                                       a CollectionMutator is set instead of a SetMutator
-+     * @see org.apache.commons.collections15.collection.CompositeCollection.CollectionMutator
-+     * @see SetMutator
-+     */
-+    public synchronized void addComposited(Collection<? extends E> c) {
-+        if (!(c instanceof Set)) {
-+            throw new IllegalArgumentException("Collections added must implement java.util.Set");
-+        }
-+
-+        for (Iterator i = this.getCollections().iterator(); i.hasNext();) {
-+            Set set = (Set) i.next();
-+            Collection intersects = CollectionUtils.intersection(set, c);
-+            if (intersects.size() > 0) {
-+                if (this.mutator == null) {
-+                    throw new UnsupportedOperationException("Collision adding composited collection with no SetMutator set");
-+                } else if (!(this.mutator instanceof SetMutator)) {
-+                    throw new UnsupportedOperationException("Collision adding composited collection to a CompositeSet with a CollectionMutator instead of a SetMutator");
-+                }
-+                ((SetMutator) this.mutator).resolveCollision(this, set, (Set) c, intersects);
-+                if (CollectionUtils.intersection(set, c).size() > 0) {
-+                    throw new IllegalArgumentException("Attempt to add illegal entry unresolved by SetMutator.resolveCollision()");
-+                }
-+            }
-+        }
-+        super.addComposited((Collection<E>[]) new Collection[]{c});
-+    }
-+
-+    /**
-+     * Add two sets to this composite
-+     *
-+     * @deprecated Superceded by the variable argument implementation of addComposited()
-+     * @throws IllegalArgumentException if c or d does not implement java.util.Set
-+     */
-+    public synchronized void addComposited(Collection<? extends E> c, Collection<? extends E> d) {
-+        if (!(c instanceof Set)) throw new IllegalArgumentException("Argument must implement java.util.Set");
-+        if (!(d instanceof Set)) throw new IllegalArgumentException("Argument must implement java.util.Set");
-+        this.addComposited(new Set[]{(Set) c, (Set) d});
-+    }
-+
-+    /**
-+     * Add an array of sets to this composite
-+     *
-+     * @param comps
-+     * @throws IllegalArgumentException if any of the collections15 in comps do not implement Set
-+     */
-+    public synchronized void addComposited(Collection<? extends E>... comps) {
-+        for (int i = comps.length - 1; i >= 0; --i) {
-+            this.addComposited(comps[i]);
-+        }
-+    }
-+
-+    /**
-+     * This can receive either a <code>CompositeCollection.CollectionMutator</code>
-+     * or a <code>CompositeSet.SetMutator</code>. If a
-+     * <code>CompositeCollection.CollectionMutator</code> is used than conflicts when adding
-+     * composited sets will throw IllegalArgumentException
-+     * <p/>
-+     */
-+    public void setMutator(CollectionMutator<E> mutator) {
-+        super.setMutator(mutator);
-+    }
-+    
-+    /* Set operations */
-+    
-+    /**
-+     * If a <code>CollectionMutator</code> is defined for this CompositeSet then this
-+     * method will be called anyway.
-+     *
-+     * @param obj Object to be removed
-+     * @return true if the object is removed, false otherwise
-+     */
-+    public boolean remove(Object obj) {
-+        for (Iterator i = this.getCollections().iterator(); i.hasNext();) {
-+            Set set = (Set) i.next();
-+            if (set.contains(obj)) return set.remove(obj);
-+        }
-+        return false;
-+    }
-+
-+
-+    /**
-+     * @see Set#equals
-+     */
-+    public boolean equals(Object obj) {
-+        if (obj instanceof Set) {
-+            Set set = (Set) obj;
-+            if (set.containsAll(this) && set.size() == this.size()) {
-+                return true;
-+            }
-+        }
-+        return false;
-+    }
-+
-+    /**
-+     * @see Set#hashCode
-+     */
-+    public int hashCode() {
-+        int code = 0;
-+        for (Iterator i = this.iterator(); i.hasNext();) {
-+            Object next = i.next();
-+            code += (next != null ? next.hashCode() : 0);
-+        }
-+        return code;
-+    }
-+
-+    /**
-+     * Define callbacks for mutation operations.
-+     * <p/>
-+     * Defining remove() on implementations of SetMutator is pointless
-+     * as they are never called by CompositeSet.
-+     */
-+    public static interface SetMutator <E> extends CompositeCollection.CollectionMutator<E> {
-+        /**
-+         * <p/>
-+         * Called when a Set is added to the CompositeSet and there is a
-+         * collision between existing and added sets.
-+         * </p>
-+         * <p/>
-+         * If <code>added</code> and <code>existing</code> still have any intersects
-+         * after this method returns an IllegalArgumentException will be thrown.
-+         * </p>
-+         *
-+         * @param comp       The CompositeSet being modified
-+         * @param existing   The Set already existing in the composite
-+         * @param added      the Set being added to the composite
-+         * @param intersects the intersection of th existing and added sets
-+         */
-+        public void resolveCollision(CompositeSet<E> comp, Set<E> existing, Set<E> added, Collection<E> intersects);
-+    }
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/ListOrderedSet.java
-@@ -0,0 +1,310 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.iterators.AbstractIteratorDecorator;
-+import org.apache.commons.collections15.list.UnmodifiableList;
-+
-+import java.util.*;
-+
-+/**
-+ * Decorates another <code>Set</code> to ensure that the order of addition
-+ * is retained and used by the iterator.
-+ * <p/>
-+ * If an object is added to the set for a second time, it will remain in the
-+ * original position in the iteration.
-+ * The order can be observed from the set via the iterator or toArray methods.
-+ * <p/>
-+ * The ListOrderedSet also has various useful direct methods. These include many
-+ * from <code>List</code>, such as <code>get(int)</code>, <code>remove(int)</code>
-+ * and <code>indexOf(int)</code>. An unmodifiable <code>List</code> view of
-+ * the set can be obtained via <code>asList()</code>.
-+ * <p/>
-+ * This class cannot implement the <code>List</code> interface directly as
-+ * various interface methods (notably equals/hashCode) are incompatable with a set.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @author Henning P. Schmiedehausen
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class ListOrderedSet <E> extends AbstractSerializableSetDecorator<E> implements Set<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -228664372470420141L;
-+
-+    /**
-+     * Internal list to hold the sequence of objects
-+     */
-+    protected final List<E> setOrder;
-+
-+    /**
-+     * Factory method to create an ordered set specifying the list and set to use.
-+     *
-+     * @param set  the set to decorate, must be empty and not null
-+     * @param list the list to decorate, must be empty and not null
-+     * @throws IllegalArgumentException if set or list is null
-+     * @throws IllegalArgumentException if either the set or list is not empty
-+     * @since Commons Collections 3.1
-+     */
-+    public static <E> ListOrderedSet<E> decorate(Set<E> set, List<E> list) {
-+        if (set == null) {
-+            throw new IllegalArgumentException("Set must not be null");
-+        }
-+        if (list == null) {
-+            throw new IllegalArgumentException("List must not be null");
-+        }
-+        if (set.size() > 0 || list.size() > 0) {
-+            throw new IllegalArgumentException("Set and List must be empty");
-+        }
-+        return new ListOrderedSet<E>(set, list);
-+    }
-+
-+    /**
-+     * Factory method to create an ordered set.
-+     * <p/>
-+     * An <code>ArrayList</code> is used to retain order.
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    public static <E> ListOrderedSet<E> decorate(Set<E> set) {
-+        return new ListOrderedSet<E>(set);
-+    }
-+
-+    /**
-+     * Factory method to create an ordered set using the supplied list to retain order.
-+     * <p/>
-+     * A <code>HashSet</code> is used for the set behaviour.
-+     *
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if list is null
-+     */
-+    public static <E> ListOrderedSet<E> decorate(List<E> list) {
-+        if (list == null) {
-+            throw new IllegalArgumentException("List must not be null");
-+        }
-+        Set<E> set = new HashSet<E>(list);
-+        list.retainAll(set);
-+
-+        return new ListOrderedSet<E>(set, list);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructs a new empty <code>ListOrderedSet</code> using
-+     * a <code>HashSet</code> and an <code>ArrayList</code> internally.
-+     *
-+     * @since Commons Collections 3.1
-+     */
-+    public ListOrderedSet() {
-+        super(new HashSet<E>());
-+        setOrder = new ArrayList<E>();
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    protected ListOrderedSet(Set<E> set) {
-+        super(set);
-+        setOrder = new ArrayList<E>(set);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies) the Set and specifies the list to use.
-+     * <p/>
-+     * The set and list must both be correctly initialised to the same elements.
-+     *
-+     * @param set  the set to decorate, must not be null
-+     * @param list the list to decorate, must not be null
-+     * @throws IllegalArgumentException if set or list is null
-+     */
-+    protected ListOrderedSet(Set<E> set, List<E> list) {
-+        super(set);
-+        if (list == null) {
-+            throw new IllegalArgumentException("List must not be null");
-+        }
-+        setOrder = list;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Gets an unmodifiable view of the order of the Set.
-+     *
-+     * @return an unmodifiable list view
-+     */
-+    public List<E> asList() {
-+        return UnmodifiableList.decorate(setOrder);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public void clear() {
-+        collection.clear();
-+        setOrder.clear();
-+    }
-+
-+    public Iterator<E> iterator() {
-+        return new OrderedSetIterator<E>(setOrder.iterator(), collection);
-+    }
-+
-+    public boolean add(E object) {
-+        if (collection.contains(object)) {
-+            // re-adding doesn't change order
-+            return collection.add(object);
-+        } else {
-+            // first add, so add to both set and list
-+            boolean result = collection.add(object);
-+            setOrder.add(object);
-+            return result;
-+        }
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        boolean result = false;
-+        for (Iterator<? extends E> it = coll.iterator(); it.hasNext();) {
-+            E object = it.next();
-+            result = result | add(object);
-+        }
-+        return result;
-+    }
-+
-+    public boolean remove(Object object) {
-+        boolean result = collection.remove(object);
-+        setOrder.remove(object);
-+        return result;
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        boolean result = false;
-+        for (Iterator it = coll.iterator(); it.hasNext();) {
-+            Object object = it.next();
-+            result = result | remove(object);
-+        }
-+        return result;
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        boolean result = collection.retainAll(coll);
-+        if (result == false) {
-+            return false;
-+        } else if (collection.size() == 0) {
-+            setOrder.clear();
-+        } else {
-+            for (Iterator it = setOrder.iterator(); it.hasNext();) {
-+                Object object = it.next();
-+                if (collection.contains(object) == false) {
-+                    it.remove();
-+                }
-+            }
-+        }
-+        return result;
-+    }
-+
-+    public Object[] toArray() {
-+        return setOrder.toArray();
-+    }
-+
-+    public <T> T[] toArray(T[] a) {
-+        return setOrder.toArray(a);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public E get(int index) {
-+        return setOrder.get(index);
-+    }
-+
-+    public int indexOf(E object) {
-+        return setOrder.indexOf(object);
-+    }
-+
-+    public void add(int index, E object) {
-+        if (contains(object) == false) {
-+            collection.add(object);
-+            setOrder.add(index, object);
-+        }
-+    }
-+
-+    public boolean addAll(int index, Collection<? extends E> coll) {
-+        boolean changed = false;
-+        for (Iterator<? extends E> it = coll.iterator(); it.hasNext();) {
-+            E object = it.next();
-+            if (contains(object) == false) {
-+                collection.add(object);
-+                setOrder.add(index, object);
-+                index++;
-+                changed = true;
-+            }
-+        }
-+        return changed;
-+    }
-+
-+    public E remove(int index) {
-+        E obj = setOrder.remove(index);
-+        remove(obj);
-+        return obj;
-+    }
-+
-+    /**
-+     * Uses the underlying List's toString so that order is achieved.
-+     * This means that the decorated Set's toString is not used, so
-+     * any custom toStrings will be ignored.
-+     */
-+    // Fortunately List.toString and Set.toString look the same
-+    public String toString() {
-+        return setOrder.toString();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Internal iterator handle remove.
-+     */
-+    static class OrderedSetIterator <E> extends AbstractIteratorDecorator<E> {
-+
-+        /**
-+         * Object we iterate on
-+         */
-+        protected final Collection<E> set;
-+        /**
-+         * Last object retrieved
-+         */
-+        protected E last;
-+
-+        private OrderedSetIterator(Iterator<E> iterator, Collection<E> set) {
-+            super(iterator);
-+            this.set = set;
-+        }
-+
-+        public E next() {
-+            last = iterator.next();
-+            return last;
-+        }
-+
-+        public void remove() {
-+            set.remove(last);
-+            iterator.remove();
-+            last = null;
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/MapBackedSet.java
-@@ -0,0 +1,163 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+
-+/**
-+ * Decorates a <code>Map</code> to obtain <code>Set</code> behaviour.
-+ * <p/>
-+ * This class is used to create a <code>Set</code> with the same properties as
-+ * the key set of any map. Thus, a ReferenceSet can be created by wrapping a
-+ * <code>ReferenceMap</code> in an instance of this class.
-+ * <p/>
-+ * Most map implementation can be used to create a set by passing in dummy values.
-+ * Exceptions include <code>BidiMap</code> implementations, as they require unique values.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.1
-+ */
-+public final class MapBackedSet <K,V> implements Set<K>, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 6723912213766056587L;
-+
-+    /**
-+     * The map being used as the backing store
-+     */
-+    protected final Map<K, V> map;
-+    /**
-+     * The dummyValue to use
-+     */
-+    protected final V dummyValue;
-+
-+    /**
-+     * Factory method to create a set from a map.
-+     *
-+     * @param map the map to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    public static <K,V> Set<K> decorate(Map<K, V> map) {
-+        return decorate(map, null);
-+    }
-+
-+    /**
-+     * Factory method to create a set from a map.
-+     *
-+     * @param map        the map to decorate, must not be null
-+     * @param dummyValue the dummy value to use
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    public static <K,V> Set<K> decorate(Map<K, V> map, V dummyValue) {
-+        if (map == null) {
-+            throw new IllegalArgumentException("The map must not be null");
-+        }
-+        return new MapBackedSet<K, V>(map, dummyValue);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param map        the map to decorate, must not be null
-+     * @param dummyValue the dummy value to use
-+     * @throws IllegalArgumentException if map is null
-+     */
-+    private MapBackedSet(Map<K, V> map, V dummyValue) {
-+        super();
-+        this.map = map;
-+        this.dummyValue = dummyValue;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public int size() {
-+        return map.size();
-+    }
-+
-+    public boolean isEmpty() {
-+        return map.isEmpty();
-+    }
-+
-+    public Iterator<K> iterator() {
-+        return map.keySet().iterator();
-+    }
-+
-+    public boolean contains(Object obj) {
-+        return map.containsKey(obj);
-+    }
-+
-+    public boolean containsAll(Collection<?> coll) {
-+        return map.keySet().containsAll(coll);
-+    }
-+
-+    public boolean add(K obj) {
-+        int size = map.size();
-+        map.put(obj, dummyValue);
-+        return (map.size() != size);
-+    }
-+
-+    public boolean addAll(Collection<? extends K> coll) {
-+        int size = map.size();
-+        for (Iterator<? extends K> it = coll.iterator(); it.hasNext();) {
-+            K obj = it.next();
-+            map.put(obj, dummyValue);
-+        }
-+        return (map.size() != size);
-+    }
-+
-+    public boolean remove(Object obj) {
-+        int size = map.size();
-+        map.remove(obj);
-+        return (map.size() != size);
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        return map.keySet().removeAll(coll);
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        return map.keySet().retainAll(coll);
-+    }
-+
-+    public void clear() {
-+        map.clear();
-+    }
-+
-+    public Object[] toArray() {
-+        return map.keySet().toArray();
-+    }
-+
-+    public <T> T[] toArray(T[] array) {
-+        return map.keySet().toArray(array);
-+    }
-+
-+    public boolean equals(Object obj) {
-+        return map.keySet().equals(obj);
-+    }
-+
-+    public int hashCode() {
-+        return map.keySet().hashCode();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/PredicatedSet.java
-@@ -0,0 +1,89 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.Predicate;
-+import org.apache.commons.collections15.collection.PredicatedCollection;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Set</code> to validate that all additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This set exists to provide validation for the decorated set.
-+ * It is normally created to decorate an empty set.
-+ * If an object cannot be added to the set, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null entries are added to the set.
-+ * <pre>Set set = PredicatedSet.decorate(new HashSet(), NotNullPredicate.INSTANCE);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedSet <E> extends PredicatedCollection<E> implements Set<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -684521469108685117L;
-+
-+    /**
-+     * Factory method to create a predicated (validating) set.
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are validated.
-+     *
-+     * @param set       the set to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if set or predicate is null
-+     * @throws IllegalArgumentException if the set contains invalid elements
-+     */
-+    public static <E> Set<E> decorate(Set<E> set, Predicate<? super E> predicate) {
-+        return new PredicatedSet<E>(set, predicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are validated.
-+     *
-+     * @param set       the set to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if set or predicate is null
-+     * @throws IllegalArgumentException if the set contains invalid elements
-+     */
-+    protected PredicatedSet(Set<E> set, Predicate<? super E> predicate) {
-+        super(set, predicate);
-+    }
-+
-+    /**
-+     * Gets the set being decorated.
-+     *
-+     * @return the decorated set
-+     */
-+    protected Set<E> getSet() {
-+        return (Set<E>) getCollection();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/PredicatedSortedSet.java
-@@ -0,0 +1,117 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.Predicate;
-+
-+import java.util.Comparator;
-+import java.util.SortedSet;
-+
-+/**
-+ * Decorates another <code>SortedSet</code> to validate that all additions
-+ * match a specified predicate.
-+ * <p/>
-+ * This set exists to provide validation for the decorated set.
-+ * It is normally created to decorate an empty set.
-+ * If an object cannot be added to the set, an IllegalArgumentException is thrown.
-+ * <p/>
-+ * One usage would be to ensure that no null entries are added to the set.
-+ * <pre>SortedSet set = PredicatedSortedSet.decorate(new TreeSet(), NotNullPredicate.INSTANCE);</pre>
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Paul Jack
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class PredicatedSortedSet <E> extends PredicatedSet<E> implements SortedSet<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -9110948148132275052L;
-+
-+    /**
-+     * Factory method to create a predicated (validating) sorted set.
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are validated.
-+     *
-+     * @param set       the set to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if set or predicate is null
-+     * @throws IllegalArgumentException if the set contains invalid elements
-+     */
-+    public static <E> SortedSet<E> decorate(SortedSet<E> set, Predicate<? super E> predicate) {
-+        return new PredicatedSortedSet<E>(set, predicate);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are validated.
-+     *
-+     * @param set       the set to decorate, must not be null
-+     * @param predicate the predicate to use for validation, must not be null
-+     * @throws IllegalArgumentException if set or predicate is null
-+     * @throws IllegalArgumentException if the set contains invalid elements
-+     */
-+    protected PredicatedSortedSet(SortedSet<E> set, Predicate<? super E> predicate) {
-+        super(set, predicate);
-+    }
-+
-+    /**
-+     * Gets the sorted set being decorated.
-+     *
-+     * @return the decorated sorted set
-+     */
-+    private SortedSet<E> getSortedSet() {
-+        return (SortedSet<E>) getCollection();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedSet<E> subSet(E fromElement, E toElement) {
-+        SortedSet sub = getSortedSet().subSet(fromElement, toElement);
-+        return new PredicatedSortedSet<E>(sub, predicate);
-+    }
-+
-+    public SortedSet<E> headSet(E toElement) {
-+        SortedSet sub = getSortedSet().headSet(toElement);
-+        return new PredicatedSortedSet<E>(sub, predicate);
-+    }
-+
-+    public SortedSet<E> tailSet(E fromElement) {
-+        SortedSet sub = getSortedSet().tailSet(fromElement);
-+        return new PredicatedSortedSet<E>(sub, predicate);
-+    }
-+
-+    public E first() {
-+        return getSortedSet().first();
-+    }
-+
-+    public E last() {
-+        return getSortedSet().last();
-+    }
-+
-+    public Comparator<? super E> comparator() {
-+        return getSortedSet().comparator();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/SynchronizedSet.java
-@@ -0,0 +1,83 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.collection.SynchronizedCollection;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Set</code> to synchronize its behaviour for a
-+ * multi-threaded environment.
-+ * <p/>
-+ * Methods are synchronized, then forwarded to the decorated set.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SynchronizedSet <E> extends SynchronizedCollection<E> implements Set<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -8304417378626543635L;
-+
-+    /**
-+     * Factory method to create a synchronized set.
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    public static <E> Set<E> decorate(Set<E> set) {
-+        return new SynchronizedSet<E>(set);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    protected SynchronizedSet(Set<E> set) {
-+        super(set);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set  the set to decorate, must not be null
-+     * @param lock the lock object to use, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    protected SynchronizedSet(Set<E> set, Object lock) {
-+        super(set, lock);
-+    }
-+
-+    /**
-+     * Gets the decorated set.
-+     *
-+     * @return the decorated set
-+     */
-+    protected Set<E> getSet() {
-+        return (Set<E>) collection;
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/SynchronizedSortedSet.java
-@@ -0,0 +1,130 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.collection.SynchronizedCollection;
-+
-+import java.util.Comparator;
-+import java.util.SortedSet;
-+
-+/**
-+ * Decorates another <code>SortedSet</code> to synchronize its behaviour
-+ * for a multi-threaded environment.
-+ * <p/>
-+ * Methods are synchronized, then forwarded to the decorated set.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class SynchronizedSortedSet <E> extends SynchronizedCollection<E> implements SortedSet<E> {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 2775582861954500111L;
-+
-+    /**
-+     * Factory method to create a synchronized set.
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    public static <E> SortedSet<E> decorate(SortedSet<E> set) {
-+        return new SynchronizedSortedSet<E>(set);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    protected SynchronizedSortedSet(SortedSet<E> set) {
-+        super(set);
-+    }
-+
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set  the set to decorate, must not be null
-+     * @param lock the lock object to use, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    protected SynchronizedSortedSet(SortedSet<E> set, Object lock) {
-+        super(set, lock);
-+    }
-+
-+    /**
-+     * Gets the decorated set.
-+     *
-+     * @return the decorated set
-+     */
-+    protected SortedSet<E> getSortedSet() {
-+        return (SortedSet<E>) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedSet<E> subSet(E fromElement, E toElement) {
-+        synchronized (lock) {
-+            SortedSet set = getSortedSet().subSet(fromElement, toElement);
-+            // the lock is passed into the constructor here to ensure that the
-+            // subset is synchronized on the same lock as the parent
-+            return new SynchronizedSortedSet<E>(set, lock);
-+        }
-+    }
-+
-+    public SortedSet<E> headSet(E toElement) {
-+        synchronized (lock) {
-+            SortedSet set = getSortedSet().headSet(toElement);
-+            // the lock is passed into the constructor here to ensure that the
-+            // headset is synchronized on the same lock as the parent
-+            return new SynchronizedSortedSet<E>(set, lock);
-+        }
-+    }
-+
-+    public SortedSet<E> tailSet(E fromElement) {
-+        synchronized (lock) {
-+            SortedSet<E> set = getSortedSet().tailSet(fromElement);
-+            // the lock is passed into the constructor here to ensure that the
-+            // tailset is synchronized on the same lock as the parent
-+            return new SynchronizedSortedSet<E>(set, lock);
-+        }
-+    }
-+
-+    public E first() {
-+        synchronized (lock) {
-+            return getSortedSet().first();
-+        }
-+    }
-+
-+    public E last() {
-+        synchronized (lock) {
-+            return getSortedSet().last();
-+        }
-+    }
-+
-+    public Comparator<? super E> comparator() {
-+        synchronized (lock) {
-+            return getSortedSet().comparator();
-+        }
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/TransformedSet.java
-@@ -0,0 +1,76 @@
-+// TODO: Not yet converted - deprecated (by me).
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.Transformer;
-+import org.apache.commons.collections15.collection.TransformedCollection;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Set</code> to transform objects that are added.
-+ * <p/>
-+ * The add methods are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ * <p>
-+ * Note: This class cannot support generics without breaking the Collection contract.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedSet extends TransformedCollection implements Set {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 306127383500410386L;
-+
-+    /**
-+     * Factory method to create a transforming set.
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param set         the set to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if set or transformer is null
-+     */
-+    public static <I,O> Set<O> decorate(Set<I> set, Transformer<? super I, ? extends O> transformer) {
-+        return new TransformedSet(set, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param set         the set to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if set or transformer is null
-+     */
-+    protected TransformedSet(Set set, Transformer transformer) {
-+        super(set, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/TransformedSortedSet.java
-@@ -0,0 +1,112 @@
-+// TODO: Not yet converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.Transformer;
-+
-+import java.util.Comparator;
-+import java.util.SortedSet;
-+
-+/**
-+ * Decorates another <code>SortedSet</code> to transform objects that are added.
-+ * <p/>
-+ * The add methods are affected by this class.
-+ * Thus objects must be removed or searched for using their transformed form.
-+ * For example, if the transformation converts Strings to Integers, you must
-+ * use the Integer form to remove objects.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TransformedSortedSet extends TransformedSet implements SortedSet {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -1675486811351124386L;
-+
-+    /**
-+     * Factory method to create a transforming sorted set.
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param set         the set to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if set or transformer is null
-+     */
-+    public static <I,O> SortedSet<O> decorate(SortedSet<I> set, Transformer<? super I, ? extends O> transformer) {
-+        return new TransformedSortedSet(set, transformer);
-+    }
-+    
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are NOT transformed.
-+     *
-+     * @param set         the set to decorate, must not be null
-+     * @param transformer the transformer to use for conversion, must not be null
-+     * @throws IllegalArgumentException if set or transformer is null
-+     */
-+    protected TransformedSortedSet(SortedSet set, Transformer transformer) {
-+        super(set, transformer);
-+    }
-+
-+    /**
-+     * Gets the decorated set.
-+     *
-+     * @return the decorated set
-+     */
-+    protected SortedSet getSortedSet() {
-+        return (SortedSet) collection;
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Object first() {
-+        return getSortedSet().first();
-+    }
-+
-+    public Object last() {
-+        return getSortedSet().last();
-+    }
-+
-+    public Comparator comparator() {
-+        return getSortedSet().comparator();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedSet subSet(Object fromElement, Object toElement) {
-+        SortedSet set = getSortedSet().subSet(fromElement, toElement);
-+        return new TransformedSortedSet(set, transformer);
-+    }
-+
-+    public SortedSet headSet(Object toElement) {
-+        SortedSet set = getSortedSet().headSet(toElement);
-+        return new TransformedSortedSet(set, transformer);
-+    }
-+
-+    public SortedSet tailSet(Object fromElement) {
-+        SortedSet set = getSortedSet().tailSet(fromElement);
-+        return new TransformedSortedSet(set, transformer);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/TypedSet.java
-@@ -0,0 +1,59 @@
-+// TODO: Not yet converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Set</code> to validate that elements
-+ * added are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @author Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TypedSet {
-+
-+    /**
-+     * Factory method to create a typed set.
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are validated.
-+     *
-+     * @param set  the set to decorate, must not be null
-+     * @param type the type to allow into the collection, must not be null
-+     * @throws IllegalArgumentException if set or type is null
-+     * @throws IllegalArgumentException if the set contains invalid elements
-+     */
-+    public static Set decorate(Set set, Class type) {
-+        return new PredicatedSet(set, InstanceofPredicate.getInstance(type));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedSet() {
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/TypedSortedSet.java
-@@ -0,0 +1,59 @@
-+// TODO: Not yet converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.functors.InstanceofPredicate;
-+
-+import java.util.SortedSet;
-+
-+/**
-+ * Decorates another <code>SortedSet</code> to validate that elements
-+ * added are of a specific type.
-+ * <p/>
-+ * The validation of additions is performed via an instanceof test against
-+ * a specified <code>Class</code>. If an object cannot be added to the
-+ * collection, an IllegalArgumentException is thrown.
-+ *
-+ * @author Stephen Colebourne
-+ * @author Matt Hall, John Watkinson, Matthew Hawthorne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public class TypedSortedSet {
-+
-+    /**
-+     * Factory method to create a typed sorted set.
-+     * <p/>
-+     * If there are any elements already in the set being decorated, they
-+     * are validated.
-+     *
-+     * @param set  the set to decorate, must not be null
-+     * @param type the type to allow into the collection, must not be null
-+     * @throws IllegalArgumentException if set or type is null
-+     * @throws IllegalArgumentException if the set contains invalid elements
-+     */
-+    public static SortedSet decorate(SortedSet set, Class type) {
-+        return new PredicatedSortedSet(set, InstanceofPredicate.getInstance(type));
-+    }
-+
-+    /**
-+     * Restrictive constructor.
-+     */
-+    protected TypedSortedSet() {
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/UnmodifiableSet.java
-@@ -0,0 +1,95 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.Set;
-+
-+/**
-+ * Decorates another <code>Set</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableSet <E> extends AbstractSerializableSetDecorator<E> implements Unmodifiable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = 6499119872185240161L;
-+
-+    /**
-+     * Factory method to create an unmodifiable set.
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    public static <E> Set<E> decorate(Set<E> set) {
-+        if (set instanceof Unmodifiable) {
-+            return set;
-+        }
-+        return new UnmodifiableSet<E>(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    private UnmodifiableSet(Set<E> set) {
-+        super(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/UnmodifiableSortedSet.java
-@@ -0,0 +1,139 @@
-+// GenericsNote: Converted.
-+/*
-+ *  Copyright 2003-2004 The Apache Software Foundation
-+ *
-+ *  Licensed under the Apache License, Version 2.0 (the "License");
-+ *  you may not use this file except in compliance with the License.
-+ *  You may obtain a copy of the License at
-+ *
-+ *      http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+package org.apache.commons.collections15.set;
-+
-+import org.apache.commons.collections15.Unmodifiable;
-+import org.apache.commons.collections15.iterators.UnmodifiableIterator;
-+
-+import java.io.IOException;
-+import java.io.ObjectInputStream;
-+import java.io.ObjectOutputStream;
-+import java.io.Serializable;
-+import java.util.Collection;
-+import java.util.Iterator;
-+import java.util.SortedSet;
-+
-+/**
-+ * Decorates another <code>SortedSet</code> to ensure it can't be altered.
-+ * <p/>
-+ * This class is Serializable from Commons Collections 3.1.
-+ *
-+ * @author Matt Hall, John Watkinson, Stephen Colebourne
-+ * @version $Revision: 1.1 $ $Date: 2005/10/11 17:05:39 $
-+ * @since Commons Collections 3.0
-+ */
-+public final class UnmodifiableSortedSet <E> extends AbstractSortedSetDecorator<E> implements Unmodifiable, Serializable {
-+
-+    /**
-+     * Serialization version
-+     */
-+    private static final long serialVersionUID = -725356885467962424L;
-+
-+    /**
-+     * Factory method to create an unmodifiable set.
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    public static <E> SortedSet<E> decorate(SortedSet<E> set) {
-+        if (set instanceof Unmodifiable) {
-+            return set;
-+        }
-+        return new UnmodifiableSortedSet<E>(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Write the collection out using a custom routine.
-+     *
-+     * @param out the output stream
-+     * @throws IOException
-+     */
-+    private void writeObject(ObjectOutputStream out) throws IOException {
-+        out.defaultWriteObject();
-+        out.writeObject(collection);
-+    }
-+
-+    /**
-+     * Read the collection in using a custom routine.
-+     *
-+     * @param in the input stream
-+     * @throws IOException
-+     * @throws ClassNotFoundException
-+     */
-+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-+        in.defaultReadObject();
-+        collection = (Collection<E>) in.readObject();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    /**
-+     * Constructor that wraps (not copies).
-+     *
-+     * @param set the set to decorate, must not be null
-+     * @throws IllegalArgumentException if set is null
-+     */
-+    private UnmodifiableSortedSet(SortedSet<E> set) {
-+        super(set);
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public Iterator<E> iterator() {
-+        return UnmodifiableIterator.decorate(getCollection().iterator());
-+    }
-+
-+    public boolean add(E object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean addAll(Collection<? extends E> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public void clear() {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean remove(Object object) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean removeAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    public boolean retainAll(Collection<?> coll) {
-+        throw new UnsupportedOperationException();
-+    }
-+
-+    //-----------------------------------------------------------------------
-+    public SortedSet<E> subSet(E fromElement, E toElement) {
-+        SortedSet<E> sub = getSortedSet().subSet(fromElement, toElement);
-+        return new UnmodifiableSortedSet<E>(sub);
-+    }
-+
-+    public SortedSet<E> headSet(E toElement) {
-+        SortedSet sub = getSortedSet().headSet(toElement);
-+        return new UnmodifiableSortedSet<E>(sub);
-+    }
-+
-+    public SortedSet<E> tailSet(E fromElement) {
-+        SortedSet<E> sub = getSortedSet().tailSet(fromElement);
-+        return new UnmodifiableSortedSet<E>(sub);
-+    }
-+
-+}
---- /dev/null
-+++ libjung-java/collections15/org/apache/commons/collections15/set/package.html
-@@ -0,0 +1,42 @@
-+<!-- $Id: package.html,v 1.1 2005/10/11 17:05:39 pents90 Exp $ -->
-+ <!--
-+   Copyright 2003-2004 The Apache Software Foundation
-+
-+   Licensed under the Apache License, Version 2.0 (the "License");
-+   you may not use this file except in compliance with the License.
-+   You may obtain a copy of the License at
-+
-+       http://www.apache.org/licenses/LICENSE-2.0
-+
-+   Unless required by applicable law or agreed to in writing, software
-+   distributed under the License is distributed on an "AS IS" BASIS,
-+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+   See the License for the specific language governing permissions and
-+   limitations under the License.
-+  -->
-+<BODY>
-+<p>
-+This package contains implementations of the
-+{@link java.util.Set Set} and
-+{@link java.util.SortedSet SortedSet} interfaces.
-+<p>
-+The implementations are in the form of direct implementations and decorators.
-+A decorator wraps another implementation of the interface to add some
-+specific additional functionality.
-+<p>
-+The following implementations are provided in the package:
-+<ul>
-+<li>CompositeSet - a set that combines multiple sets into one
-+</ul>
-+The following decorators are provided in the package:
-+<ul>
-+<li>Synchronized - synchronizes method access for multi-threaded environments
-+<li>Unmodifiable - ensures the collection cannot be altered
-+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
-+<li>Typed - ensures that only elements that are of a specific type can be added
-+<li>Transformed - transforms each element added
-+<li>ListOrdered - ensures that insertion order is retained
-+<li>MapBackedSet - a set formed by decorating a Map
-+</ul>
-+</pre>
-+</BODY>
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index 692f4e8..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1 +0,0 @@
-collections15
diff --git a/debian/patches/use-apache-commons-collections b/debian/patches/use-apache-commons-collections
new file mode 100644
index 0000000..181ec19
--- /dev/null
+++ b/debian/patches/use-apache-commons-collections
@@ -0,0 +1,113 @@
+Description: Fix incompatibilities between collections15 and collection4
+Author: Michael R. Crusoe <mcrusoe at msu.edu>
+Forwarded: no
+Last-Updated: 2015-02-21
+
+Inspired by
+http://sources.debian.net/data/main/g/geogebra/4.0.34.0+dfsg1-3/debian/patches/use-apache-commons-collections.patch
+
+References include http://commons.apache.org/proper/commons-collections/javadocs/api-release/index.html
+and http://commons.apache.org/proper/commons-collections/release_4_0.html
+
+--- a/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/scoring/PageRank.java
++++ b/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/scoring/PageRank.java
+@@ -52,7 +52,7 @@
+      * @param edge_weight the edge weights (transition probabilities)
+      * @param alpha the probability of taking a random jump to an arbitrary vertex
+      */
+-    public PageRank(Hypergraph<V,E> graph, Transformer<E, ? extends Number> edge_weight, double alpha)
++    public PageRank(Hypergraph<V,E> graph, Transformer/*<E, ? extends Number>*/ edge_weight, double alpha)
+     {
+         super(graph, edge_weight, ScoringUtils.getUniformRootPrior(graph.getVertices()), alpha);
+     }
+--- a/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/shortestpath/DijkstraDistance.java
++++ b/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/shortestpath/DijkstraDistance.java
+@@ -65,7 +65,7 @@
+ public class DijkstraDistance<V,E> implements Distance<V>
+ {
+     protected Hypergraph<V,E> g;
+-    protected Transformer<E,? extends Number> nev;
++    protected Transformer/*<E,? extends Number> */ nev;
+     protected Map<V,SourceData> sourceMap;   // a map of source vertices to an instance of SourceData
+     protected boolean cached;
+     protected double max_distance;
+@@ -81,7 +81,7 @@
+      * @param nev   the class responsible for returning weights for edges
+      * @param cached    specifies whether the results are to be cached
+      */
+-    public DijkstraDistance(Hypergraph<V,E> g, Transformer<E,? extends Number> nev, boolean cached) {
++    public DijkstraDistance(Hypergraph<V,E> g, Transformer/*<E,? extends Number>*/ nev, boolean cached) {
+         this.g = g;
+         this.nev = nev;
+         this.sourceMap = new HashMap<V,SourceData>();
+@@ -98,7 +98,7 @@
+      * @param g     the graph on which distances will be calculated
+      * @param nev   the class responsible for returning weights for edges
+      */
+-    public DijkstraDistance(Hypergraph<V,E> g, Transformer<E,? extends Number> nev) {
++    public DijkstraDistance(Hypergraph<V,E> g, Transformer/*<E,? extends Number> */ nev) {
+         this(g, nev, true);
+     }
+     
+@@ -198,7 +198,7 @@
+                 {
+                     if (!sd.distances.containsKey(w))
+                     {
+-                        double edge_weight = nev.transform(e).doubleValue();
++                        double edge_weight = ((Number) nev.transform(e)).doubleValue();
+                         if (edge_weight < 0)
+                             throw new IllegalArgumentException("Edges weights must be non-negative");
+                         double new_dist = v_dist + edge_weight;
+--- a/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/layout/AbstractLayout.java
++++ b/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/layout/AbstractLayout.java
+@@ -69,9 +69,9 @@
+ 	}
+ 	
+     @SuppressWarnings("unchecked")
+-    protected AbstractLayout(Graph<V,E> graph, Transformer<V,Point2D> initializer) {
++    protected AbstractLayout(Graph<V,E> graph, Transformer/*<V,Point2D>*/ initializer) {
+ 		this.graph = graph;
+-		Transformer<V, ? extends Object> chain = 
++		Transformer/*<V, ? extends Object>*/ chain = 
+ 			ChainedTransformer.chainedTransformer(initializer, CloneTransformer.cloneTransformer());
+ 		this.locations = LazyMap.lazyMap(new HashMap<V,Point2D>(), (Transformer<V,Point2D>)chain);
+ 		initialized = true;
+@@ -83,9 +83,9 @@
+ 	}
+ 	
+ 	@SuppressWarnings("unchecked")
+-    protected AbstractLayout(Graph<V,E> graph, Transformer<V,Point2D> initializer, Dimension size) {
++    protected AbstractLayout(Graph<V,E> graph, Transformer/*<V,Point2D>*/ initializer, Dimension size) {
+ 		this.graph = graph;
+-		Transformer<V, ? extends Object> chain = 
++		Transformer/*<V, ? extends Object>*/ chain = 
+ 			ChainedTransformer.chainedTransformer(initializer, CloneTransformer.cloneTransformer());
+ 		this.locations = LazyMap.lazyMap(new HashMap<V,Point2D>(), (Transformer<V,Point2D>)chain);
+ 		this.size = size;
+@@ -139,11 +139,11 @@
+     }
+     
+     @SuppressWarnings("unchecked")
+-    public void setInitializer(Transformer<V,Point2D> initializer) {
++    public void setInitializer(Transformer/*<V,Point2D>*/ initializer) {
+     	if(this.equals(initializer)) {
+     		throw new IllegalArgumentException("Layout cannot be initialized with itself");
+     	}
+-		Transformer<V, ? extends Object> chain = 
++		Transformer/*<V, ? extends Object>*/ chain = 
+ 			ChainedTransformer.chainedTransformer(initializer, CloneTransformer.cloneTransformer());
+     	this.locations = LazyMap.lazyMap(new HashMap<V,Point2D>(), (Transformer<V, Point2D>)chain);
+     	initialized = true;
+--- a/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest2.java
++++ b/jung-algorithms-2.0.1-sources/edu/uci/ics/jung/algorithms/shortestpath/MinimumSpanningForest2.java
+@@ -28,8 +28,8 @@
+ 	
+ 	protected Graph<V,E> graph;
+ 	protected Forest<V,E> forest;
+-	protected Transformer<E,Double> weights = 
+-		(Transformer<E,Double>)new ConstantTransformer<Double>(1.0);
++	protected Transformer/*<E,Double>*/ weights = 
++		ConstantTransformer.constantTransformer(1.0);
+ 	
+ 	/**
+ 	 * create a Forest from the supplied Graph and supplied Factory, which
diff --git a/debian/rules b/debian/rules
index c6829d1..0033b25 100755
--- a/debian/rules
+++ b/debian/rules
@@ -3,23 +3,23 @@
 DH_VERBOSE := 1
 
 export JAVA_HOME=/usr/lib/jvm/default-java
-export CLASSPATH=/usr/share/java/commons-collections4.jar:/usr/share/java/colt.jar:./collections15.jar:./jung-api-2.0.1.jar
+export CLASSPATH=/usr/share/java/commons-collections4.jar:/usr/share/java/colt.jar:./jung-api-2.0.1.jar
 
 %:
 	dh $@ --with javahelper
 
 override_dh_auto_build:
 	for jar in *.jar; do mkdir $${jar%%.jar}; cd $${jar%%.jar}; \
-		unzip ../$${jar}; cd ..; done
-		#find . -type f | xargs sed -i -e \
-		#'s/org.apache.commons.collections15/org.apache.commons.collections4/' \
-		#-e 's/org.apache.commons.collections4.Buffer/java.util.Queue/' \
-		#-e 's/org.apache.commons.collections4.buffer.UnboundedFifoBuffer/java.util.LinkedList/' \
-		#-e 's/UnboundedFifoBuffer/LinkedList/' \
-		#-e 's/Buffer/Queue/' \
-		#-e 's/LazyMap.decorate/LazyMap.lazyMap/' \
-		#-e 's/MapTransformer.getInstance/MapTransformer.mapTransformer/' \
-		#-e 's/ChainedTransformer.getInstance/ChainedTransformer.chainedTransformer/' \
-		#-e 's/CloneTransformer.getInstance/CloneTransformer.cloneTransformer/' ;
-		# this _almost_ worked :-(
+		unzip ../$${jar}; find . -type f | xargs sed -i -e \
+		's/org.apache.commons.collections15/org.apache.commons.collections4/' \
+		-e 's/org.apache.commons.collections4.Buffer/java.util.Queue/' \
+		-e 's/org.apache.commons.collections4.buffer.UnboundedFifoBuffer/java.util.LinkedList/' \
+		-e 's/UnboundedFifoBuffer/LinkedList/' \
+		-e 's/Buffer</Queue</' \
+		-e 's/LazyMap.decorate/LazyMap.lazyMap/' \
+		-e 's/MapTransformer.getInstance/MapTransformer.mapTransformer/' \
+		-e 's/ChainedTransformer.getInstance/ChainedTransformer.chainedTransformer/' \
+		-e 's/CloneTransformer.getInstance/CloneTransformer.cloneTransformer/' ; \
+		cd ..; done;
+	patch -p1 < debian/patches/use-apache-commons-collections
 	dh_auto_build

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/libjung-java.git



More information about the debian-med-commit mailing list