/*******************************************************************************
 * Copyright (c) 2005, 2010 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.utility.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;
import java.util.RandomAccess;
import java.util.TreeSet;
import java.util.Vector;

import org.eclipse.jpt.common.utility.internal.iterables.ArrayIterable;
import org.eclipse.jpt.common.utility.internal.iterators.ArrayIterator;
import org.eclipse.jpt.common.utility.internal.iterators.ArrayListIterator;
import org.eclipse.jpt.common.utility.internal.iterators.SingleElementIterator;
import org.eclipse.jpt.common.utility.internal.iterators.SingleElementListIterator;
import org.eclipse.jpt.common.utility.internal.iterators.SuperIteratorWrapper;

/**
 * {@link Collection}-related utility methods.
 */
public final class CollectionTools {

	// ********** add all **********

	/**
	 * Add all the elements returned by the specified iterable
	 * to the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.addAll(Iterable iterable)</code>
	 */
	public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable) {
		return addAll(collection, iterable.iterator());
	}

	/**
	 * Add all the elements returned by the specified iterable
	 * to the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.addAll(Iterable iterable)</code>
	 */
	public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable, int size) {
		return addAll(collection, iterable.iterator(), size);
	}

	/**
	 * Add all the elements returned by the specified iterator
	 * to the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.addAll(Iterator iterator)</code>
	 */
	public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator) {
		return iterator.hasNext() ? addAll_(collection, iterator) : false;
	}

	/**
	 * assume the iterator is not empty
	 */
	private static <E> boolean addAll_(Collection<? super E> collection, Iterator<? extends E> iterator) {
		boolean modified = false;
		while (iterator.hasNext()) {
			modified |= collection.add(iterator.next());
		}
		return modified;
	}

	/**
	 * Add all the elements returned by the specified iterator
	 * to the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.addAll(Iterator iterator)</code>
	 */
	public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator, int size) {
		return iterator.hasNext() ? collection.addAll(list(iterator, size)) : false;
	}

	/**
	 * Add all the elements in the specified array
	 * to the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.addAll(Object[] array)</code>
	 */
	public static <E> boolean addAll(Collection<? super E> collection, E... array) {
		return (array.length == 0) ? false : addAll_(collection, array);
	}

	/**
	 * assume the array is not empty
	 */
	private static <E> boolean addAll_(Collection<? super E> collection, E... array) {
		boolean modified = false;
		for (E element : array) {
			modified |= collection.add(element);
		}
		return modified;
	}

	/**
	 * Add all the elements returned by the specified iterable
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 * <p>
	 * <code>List.addAll(Iterable iterable)</code>
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable) {
		return addAll(list, index, iterable.iterator());
	}

	/**
	 * Add all the elements returned by the specified iterable
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 * <p>
	 * <code>List.addAll(Iterable iterable)</code>
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable, int size) {
		return addAll(list, index, iterable.iterator(), size);
	}

	/**
	 * Add all the elements returned by the specified iterator
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 * <p>
	 * <code>List.addAll(Iterator iterator)</code>
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator) {
		return iterator.hasNext() ? list.addAll(index, list(iterator)) : false;
	}

	/**
	 * Add all the elements returned by the specified iterator
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 * <p>
	 * <code>List.addAll(Iterator iterator)</code>
	 */
	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator, int size) {
		return iterator.hasNext() ? list.addAll(index, list(iterator, size)) : false;
	}

	/**
	 * Add all the elements in the specified array
	 * to the specified list at the specified index.
	 * Return whether the list changed as a result.
	 * <p>
	 * <code>List.addAll(Object[] array)</code>
	 */
	public static <E> boolean addAll(List<? super E> list, int index, E... array) {
		return (array.length == 0) ? false : list.addAll(index, Arrays.asList(array));
	}


	// ********** bag **********

	/**
	 * Return a bag corresponding to the specified enumeration.
	 * <p>
	 * <code>HashBag(Enumeration enumeration)</code>
	 */
	public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration) {
		return bag(enumeration, new HashBag<E>());
	}

	/**
	 * Return a bag corresponding to the specified enumeration.
	 * The specified enumeration size is a performance hint.
	 * <p>
	 * <code>HashBag(Enumeration enumeration)</code>
	 */
	public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, int enumerationSize) {
		return bag(enumeration, new HashBag<E>(enumerationSize));
	}

	private static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, HashBag<E> bag) {
		while (enumeration.hasMoreElements()) {
			bag.add(enumeration.nextElement());
		}
		return bag;
	}

	/**
	 * Return a bag corresponding to the specified iterable.
	 * <p>
	 * <code>HashBag(Iterable iterable)</code>
	 */
	public static <E> HashBag<E> bag(Iterable<? extends E> iterable) {
		return bag(iterable.iterator());
	}

	/**
	 * Return a bag corresponding to the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>HashBag(Iterable iterable)</code>
	 */
	public static <E> HashBag<E> bag(Iterable<? extends E> iterable, int iterableSize) {
		return bag(iterable.iterator(), iterableSize);
	}

	/**
	 * Return a bag corresponding to the specified iterator.
	 * <p>
	 * <code>HashBag(Iterator iterator)</code>
	 */
	public static <E> HashBag<E> bag(Iterator<? extends E> iterator) {
		return bag(iterator, new HashBag<E>());
	}

	/**
	 * Return a bag corresponding to the specified iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>HashBag(Iterator iterator)</code>
	 */
	public static <E> HashBag<E> bag(Iterator<? extends E> iterator, int iteratorSize) {
		return bag(iterator, new HashBag<E>(iteratorSize));
	}

	private static <E> HashBag<E> bag(Iterator<? extends E> iterator, HashBag<E> bag) {
		while (iterator.hasNext()) {
			bag.add(iterator.next());
		}
		return bag;
	}

	/**
	 * Return a bag corresponding to the specified array.
	 * <p>
	 * <code>HashBag(Object[] array)</code>
	 */
	public static <E> HashBag<E> bag(E... array) {
		int len = array.length;
		HashBag<E> bag = new HashBag<E>(len);
		for (E item : array) {
			bag.add(item);
		}
		return bag;
	}


	// ********** collection **********

	/**
	 * Return a collection corresponding to the specified enumeration.
	 */
	public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration) {
		return bag(enumeration);
	}

	/**
	 * Return a collection corresponding to the specified enumeration.
	 * The specified enumeration size is a performance hint.
	 */
	public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration, int enumerationSize) {
		return bag(enumeration, enumerationSize);
	}

	/**
	 * Return a collection corresponding to the specified iterable.
	 */
	public static <E> HashBag<E> collection(Iterable<? extends E> iterable) {
		return collection(iterable.iterator());
	}

	/**
	 * Return a collection corresponding to the specified iterable.
	 * The specified iterable size is a performance hint.
	 */
	public static <E> HashBag<E> collection(Iterable<? extends E> iterable, int iterableSize) {
		return collection(iterable.iterator(), iterableSize);
	}

	/**
	 * Return a collection corresponding to the specified iterator.
	 */
	public static <E> HashBag<E> collection(Iterator<? extends E> iterator) {
		return bag(iterator);
	}

	/**
	 * Return a collection corresponding to the specified iterator.
	 * The specified iterator size is a performance hint.
	 */
	public static <E> HashBag<E> collection(Iterator<? extends E> iterator, int iteratorSize) {
		return bag(iterator, iteratorSize);
	}

	/**
	 * Return a collection corresponding to the specified array.
	 */
	public static <E> HashBag<E> collection(E... array) {
		return bag(array);
	}


	// ********** contains **********

	/**
	 * Return whether the specified enumeration contains the
	 * specified element.
	 * <p>
	 * <code>Enumeration.contains(Object o)</code>
	 */
	public static boolean contains(Enumeration<?> enumeration, Object value) {
		if (value == null) {
			while (enumeration.hasMoreElements()) {
				if (enumeration.nextElement() == null) {
					return true;
				}
			}
		} else {
			while (enumeration.hasMoreElements()) {
				if (value.equals(enumeration.nextElement())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Return whether the specified iterable contains the
	 * specified element.
	 * <p>
	 * <code>Iterable.contains(Object o)</code>
	 */
	public static boolean contains(Iterable<?> iterable, Object value) {
		return contains(iterable.iterator(), value);
	}

	/**
	 * Return whether the specified iterator contains the
	 * specified element.
	 * <p>
	 * <code>Iterator.contains(Object o)</code>
	 */
	public static boolean contains(Iterator<?> iterator, Object value) {
		if (value == null) {
			while (iterator.hasNext()) {
				if (iterator.next() == null) {
					return true;
				}
			}
		} else {
			while (iterator.hasNext()) {
				if (value.equals(iterator.next())) {
					return true;
				}
			}
		}
		return false;
	}


	// ********** contains all **********

	/**
	 * Return whether the specified collection contains all of the
	 * elements in the specified iterable.
	 * <p>
	 * <code>Collection.containsAll(Iterable iterable)</code>
	 */
	public static boolean containsAll(Collection<?> collection, Iterable<?> iterable) {
		return containsAll(collection, iterable.iterator());
	}

	/**
	 * Return whether the specified collection contains all of the
	 * elements in the specified iterator.
	 * <p>
	 * <code>Collection.containsAll(Iterator iterator)</code>
	 */
	public static boolean containsAll(Collection<?> collection, Iterator<?> iterator) {
		while (iterator.hasNext()) {
			if ( ! collection.contains(iterator.next())) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Return whether the specified collection contains all of the
	 * elements in the specified array.
	 * <p>
	 * <code>Collection.containsAll(Object[] array)</code>
	 */
	public static boolean containsAll(Collection<?> collection, Object... array) {
		for (int i = array.length; i-- > 0; ) {
			if ( ! collection.contains(array[i])) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Return whether the specified iterable contains all of the
	 * elements in the specified collection.
	 * <p>
	 * <code>Iterable.containsAll(Collection collection)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable, Collection<?> collection) {
		return containsAll(iterable.iterator(), collection);
	}

	/**
	 * Return whether the specified iterable contains all of the
	 * elements in the specified collection.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.containsAll(Collection collection)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Collection<?> collection) {
		return containsAll(iterable.iterator(), iterableSize, collection);
	}

	/**
	 * Return whether the specified iterable 1 contains all of the
	 * elements in the specified iterable 2.
	 * <p>
	 * <code>Iterable.containsAll(Iterable iterable)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable1, Iterable<?> iterable2) {
		return containsAll(iterable1.iterator(), iterable2.iterator());
	}

	/**
	 * Return whether the specified iterable 1 contains all of the
	 * elements in the specified iterable 2.
	 * The specified iterable 1 size is a performance hint.
	 * <p>
	 * <code>Iterable.containsAll(Iterable iterable)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable1, int iterable1Size, Iterable<?> iterable2) {
		return containsAll(iterable1.iterator(), iterable1Size, iterable2.iterator());
	}

	/**
	 * Return whether the specified iterable contains all of the
	 * elements in the specified iterator.
	 * <p>
	 * <code>Iterable.containsAll(Iterator iterator)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable, Iterator<?> iterator) {
		return containsAll(iterable.iterator(), iterator);
	}

	/**
	 * Return whether the specified iterable contains all of the
	 * elements in the specified iterator.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.containsAll(Iterator iterator)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Iterator<?> iterator) {
		return containsAll(iterable.iterator(), iterableSize, iterator);
	}

	/**
	 * Return whether the specified iterable contains all of the
	 * elements in the specified array.
	 * <p>
	 * <code>Iterable.containsAll(Object[] array)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable, Object... array) {
		return containsAll(iterable.iterator(), array);
	}

	/**
	 * Return whether the specified iterable contains all of the
	 * elements in the specified array.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.containsAll(Object[] array)</code>
	 */
	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Object... array) {
		return containsAll(iterable.iterator(), iterableSize, array);
	}

	/**
	 * Return whether the specified iterator contains all of the
	 * elements in the specified collection.
	 * <p>
	 * <code>Iterator.containsAll(Collection collection)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator, Collection<?> collection) {
		return set(iterator).containsAll(collection);
	}

	/**
	 * Return whether the specified iterator contains all of the
	 * elements in the specified collection.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.containsAll(Collection collection)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Collection<?> collection) {
		return set(iterator, iteratorSize).containsAll(collection);
	}

	/**
	 * Return whether the specified iterator contains all of the
	 * elements in the specified iterable.
	 * <p>
	 * <code>Iterator.containsAll(Iterable iterable)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator, Iterable<?> iterable) {
		return containsAll(set(iterator), iterable);
	}

	/**
	 * Return whether the specified iterator contains all of the
	 * elements in the specified iterable.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.containsAll(Iterable iterable)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Iterable<?> iterable) {
		return containsAll(set(iterator, iteratorSize), iterable);
	}

	/**
	 * Return whether the specified iterator 1 contains all of the
	 * elements in the specified iterator 2.
	 * <p>
	 * <code>Iterator.containsAll(Iterator iterator)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator1, Iterator<?> iterator2) {
		return containsAll(set(iterator1), iterator2);
	}

	/**
	 * Return whether the specified iterator 1 contains all of the
	 * elements in the specified iterator 2.
	 * The specified iterator 1 size is a performance hint.
	 * <p>
	 * <code>Iterator.containsAll(Iterator iterator)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator1, int iterator1Size, Iterator<?> iterator2) {
		return containsAll(set(iterator1, iterator1Size), iterator2);
	}

	/**
	 * Return whether the specified iterator contains all of the
	 * elements in the specified array.
	 * <p>
	 * <code>Iterator.containsAll(Object[] array)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator, Object... array) {
		return containsAll(set(iterator), array);
	}

	/**
	 * Return whether the specified iterator contains all of the
	 * elements in the specified array.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.containsAll(Object[] array)</code>
	 */
	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Object... array) {
		return containsAll(set(iterator, iteratorSize), array);
	}


	// ********** diff **********

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different, beginning at the end.
	 * If the lists are identical, return -1.
	 * If the lists are different sizes, return the index of the
	 * last element in the longer list.
	 * Use the elements' {@link Object#equals(Object)} method to compare the
	 * elements.
	 * <p>
	 * <code>Collections.diffEnd(List list1, List list2)</code>
	 */
	public static int diffEnd(List<?> list1, List<?> list2) {
		return ArrayTools.diffEnd(list1.toArray(), list2.toArray());
	}

	/**
	 * Return the range of elements in the specified
	 * arrays that are different.
	 * If the arrays are identical, return [size, -1].
	 * Use the elements' {@link Object#equals(Object)} method to compare the
	 * elements.
	 * <p>
	 * <code>Collections.diffRange(List list1, List list2)</code>
	 * @see #diffStart(List, List)
	 * @see #diffEnd(List, List)
	 */
	public static Range diffRange(List<?> list1, List<?> list2) {
		return ArrayTools.diffRange(list1.toArray(), list2.toArray());
	}

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different. If the lists are identical, return
	 * the size of the two lists (i.e. one past the last index).
	 * If the lists are different sizes and all the elements in
	 * the shorter list match their corresponding elements in
	 * the longer list, return the size of the shorter list
	 * (i.e. one past the last index of the shorter list).
	 * Use the elements' {@link Object#equals(Object)} method to compare the
	 * elements.
	 * <p>
	 * <code>Collections.diffStart(List list1, List list2)</code>
	 */
	public static int diffStart(List<?> list1, List<?> list2) {
		return ArrayTools.diffStart(list1.toArray(), list2.toArray());
	}


	// ********** identity diff **********

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different, beginning at the end.
	 * If the lists are identical, return -1.
	 * If the lists are different sizes, return the index of the
	 * last element in the longer list.
	 * Use object identity to compare the elements.
	 * <p>
	 * <code>Collections.identityDiffEnd(List list1, List list2)</code>
	 */
	public static int identityDiffEnd(List<?> list1, List<?> list2) {
		return ArrayTools.identityDiffEnd(list1.toArray(), list2.toArray());
	}

	/**
	 * Return the range of elements in the specified
	 * arrays that are different.
	 * If the arrays are identical, return [size, -1].
	 * Use object identity to compare the elements.
	 * <p>
	 * <code>Collections.identityDiffStart(List list1, List list2)</code>
	 * @see #identityDiffStart(List, List)
	 * @see #identityDiffEnd(List, List)
	 */
	public static Range identityDiffRange(List<?> list1, List<?> list2) {
		return ArrayTools.identityDiffRange(list1.toArray(), list2.toArray());
	}

	/**
	 * Return the index of the first elements in the specified
	 * lists that are different. If the lists are identical, return
	 * the size of the two lists (i.e. one past the last index).
	 * If the lists are different sizes and all the elements in
	 * the shorter list match their corresponding elements in
	 * the longer list, return the size of the shorter list
	 * (i.e. one past the last index of the shorter list).
	 * Use object identity to compare the elements.
	 * <p>
	 * <code>Collections.identityDiffStart(List list1, List list2)</code>
	 */
	public static int identityDiffStart(List<?> list1, List<?> list2) {
		return ArrayTools.identityDiffStart(list1.toArray(), list2.toArray());
	}


	// ********** elements are equal **********

	/**
	 * Return whether the specified iterables do not return the same elements
	 * in the same order.
	 */
	public static boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {
		return elementsAreDifferent(iterable1.iterator(), iterable2.iterator());
	}

	/**
	 * Return whether the specified iterators do not return the same elements
	 * in the same order.
	 */
	public static boolean elementsAreDifferent(Iterator<?> iterator1, Iterator<?> iterator2) {
		return ! elementsAreEqual(iterator1, iterator2);
	}

	/**
	 * Return whether the specified iterables return equal elements
	 * in the same order.
	 * <p>
	 * <code>Iterable.elementsAreEqual(Iterable iterable)</code>
	 */
	public static boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {
		return elementsAreEqual(iterable1.iterator(), iterable2.iterator());
	}

	/**
	 * Return whether the specified iterators return equal elements
	 * in the same order.
	 * <p>
	 * <code>Iterator.elementsAreEqual(Iterator iterator)</code>
	 */
	public static boolean elementsAreEqual(Iterator<?> iterator1, Iterator<?> iterator2) {
		while (iterator1.hasNext() && iterator2.hasNext()) {
			if (Tools.valuesAreDifferent(iterator1.next(), iterator2.next())) {
				return false;
			}
		}
		return ! (iterator1.hasNext() || iterator2.hasNext());
	}


	// ********** elements are identical **********

	/**
	 * Return whether the specified iterables return the same elements.
	 * <p>
	 * <code>Iterable.identical(Iterable iterable)</code>
	 */
	public static boolean elementsAreIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {
		return elementsAreIdentical(iterable1.iterator(), iterable2.iterator());
	}

	/**
	 * Return whether the specified iterators return the same elements.
	 * <p>
	 * <code>Iterator.identical(Iterator iterator)</code>
	 */
	public static boolean elementsAreIdentical(Iterator<?> iterator1, Iterator<?> iterator2) {
		while (iterator1.hasNext() && iterator2.hasNext()) {
			if (iterator1.next() != iterator2.next()) {
				return false;
			}
		}
		return ! (iterator1.hasNext() || iterator2.hasNext());
	}


	// ********** get **********

	/**
	 * Return the element corresponding to the specified index
	 * in the specified iterable.
	 * <p>
	 * <code>Iterable.get(int index)</code>
	 */
	public static <E> E get(Iterable<? extends E> iterable, int index) {
		return get(iterable.iterator(), index);
	}

	/**
	 * Return the element corresponding to the specified index
	 * in the specified iterator.
	 * <p>
	 * <code>Iterator.get(int index)</code>
	 */
	public static <E> E get(Iterator<? extends E> iterator, int index) {
		int i = 0;
		while (iterator.hasNext()) {
			E next = iterator.next();
			if (i++ == index) {
				return next;
			}
		}
		throw new IndexOutOfBoundsException(String.valueOf(index) + ':' + String.valueOf(i));
	}


	// ********** hash code **********

	public static int hashCode(Iterable<?> iterable) {
		if (iterable == null) {
			return 0;
		}
		int hash = 1;
		for (Object element : iterable) {
			hash = 31 * hash + (element == null ? 0 : element.hashCode());
		}
		return hash;
	}


	// ********** index of **********

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified iterable;
	 * return -1 if there is no such index.
	 * <p>
	 * <code>Iterable.indexOf(Object o)</code>
	 */
	public static int indexOf(Iterable<?> iterable, Object value) {
		return indexOf(iterable.iterator(), value);
	}

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified iterator;
	 * return -1 if there is no such index.
	 * <p>
	 * <code>Iterator.indexOf(Object o)</code>
	 */
	public static int indexOf(Iterator<?> iterator, Object value) {
		if (value == null) {
			for (int i = 0; iterator.hasNext(); i++) {
				if (iterator.next() == null) {
					return i;
				}
			}
		} else {
			for (int i = 0; iterator.hasNext(); i++) {
				if (value.equals(iterator.next())) {
					return i;
				}
			}
		}
		return -1;
	}


	// ********** insertion index of **********

	/**
	 * Return an index of where the specified comparable object
	 * can be inserted into the specified sorted list and still keep
	 * the list sorted. If the specified sorted list is an instance of
	 * {@link RandomAccess} return the <em>maximum</em> insertion index;
	 * otherwise return the <em>minimum</em> insertion index.
	 */
	public static <E extends Comparable<? super E>> int insertionIndexOf(List<E> sortedList, Comparable<E> value) {
		if (sortedList instanceof RandomAccess) {
			for (int i = sortedList.size(); i-- > 0; ) {
				if (value.compareTo(sortedList.get(i)) >= 0) {
					return i + 1;
				}
			}
			return 0;
		}
		int i = 0;
		for (E element : sortedList) {
			if (value.compareTo(element) <= 0) {
				return i;
			}
			i++;
		}
		return i;
	}

	/**
	 * Return an index of where the specified comparable object
	 * can be inserted into the specified sorted list and still keep
	 * the list sorted. If the specified sorted list is an instance of
	 * {@link RandomAccess} return the <em>maximum</em> insertion index;
	 * otherwise return the <em>minimum</em> insertion index.
	 */
	public static <E> int insertionIndexOf(List<E> sortedList, E value, Comparator<? super E> comparator) {
		if (sortedList instanceof RandomAccess) {
			for (int i = sortedList.size(); i-- > 0; ) {
				if (comparator.compare(value, sortedList.get(i)) >= 0) {
					return i + 1;
				}
			}
			return 0;
		}
		int i = 0;
		for (E element : sortedList) {
			if (comparator.compare(value, element) <= 0) {
				return i;
			}
			i++;
		}
		return i;
	}


	// ********** iterable/iterator **********

	/**
	 * Return an iterable on the elements in the specified array.
	 * <p>
	 * <code>Arrays.iterable(Object[] array)</code>
	 */
	public static <E> Iterable<E> iterable(E... array) {
		return new ArrayIterable<E>(array);
	}

	/**
	 * Return an iterator on the elements in the specified array.
	 * <p>
	 * <code>Arrays.iterator(Object[] array)</code>
	 */
	public static <E> Iterator<E> iterator(E... array) {
		return new ArrayIterator<E>(array);
	}


	// ********** last **********

	/**
	 * Return the specified iterable's last element.
	 * <p>
	 * <code>Iterable.last()</code>
	 * 
     * @exception java.util.NoSuchElementException iterable is empty.
	 */
	public static <E> E last(Iterable<E> iterable) {
		return last(iterable.iterator());
	}

	/**
	 * Return the specified iterator's last element.
	 * <p>
	 * <code>Iterator.last()</code>
	 * 
     * @exception java.util.NoSuchElementException iterator is empty.
	 */
	public static <E> E last(Iterator<E> iterator) {
		E last;
		do {
			last = iterator.next();
		} while (iterator.hasNext());
		return last;
	}


	// ********** last index of **********

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified iterable;
	 * return -1 if there is no such index.
	 * <p>
	 * <code>Iterable.lastIndexOf(Object o)
	 */
	public static int lastIndexOf(Iterable<?> iterable, Object value) {
		return lastIndexOf(iterable.iterator(), value);
	}

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified iterable;
	 * return -1 if there is no such index.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.lastIndexOf(Object o)
	 */
	public static int lastIndexOf(Iterable<?> iterable, int iterableSize, Object value) {
		return lastIndexOf(iterable.iterator(), iterableSize, value);
	}

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified iterator;
	 * return -1 if there is no such index.
	 * <p>
	 * <code>Iterator.lastIndexOf(Object o)
	 */
	public static int lastIndexOf(Iterator<?> iterator, Object value) {
		return iterator.hasNext() ? list(iterator).lastIndexOf(value) : -1;
	}

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified iterator;
	 * return -1 if there is no such index.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.lastIndexOf(Object o)
	 */
	public static int lastIndexOf(Iterator<?> iterator, int iteratorSize, Object value) {
		return iterator.hasNext() ? list(iterator, iteratorSize).lastIndexOf(value) : -1;
	}


	// ********** list **********

	/**
	 * Return a list corresponding to the specified iterable.
	 * <p>
	 * <code>Iterable.toList()</code>
	 */
	public static <E> ArrayList<E> list(Iterable<? extends E> iterable) {
		return list(iterable.iterator());
	}

	/**
	 * Return a list corresponding to the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.toList()</code>
	 */
	public static <E> ArrayList<E> list(Iterable<? extends E> iterable, int iterableSize) {
		return list(iterable.iterator(), iterableSize);
	}

	/**
	 * Return a list corresponding to the specified iterator.
	 * <p>
	 * <code>Iterator.toList()</code>
	 */
	public static <E> ArrayList<E> list(Iterator<? extends E> iterator) {
		return list(iterator, new ArrayList<E>());
	}

	/**
	 * Return a list corresponding to the specified iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.toList()</code>
	 */
	public static <E> ArrayList<E> list(Iterator<? extends E> iterator, int iteratorSize) {
		return list(iterator, new ArrayList<E>(iteratorSize));
	}

	private static <E> ArrayList<E> list(Iterator<? extends E> iterator, ArrayList<E> list) {
		while (iterator.hasNext()) {
			list.add(iterator.next());
		}
		return list;
	}

	/**
	 * Return a list corresponding to the specified array.
	 * Unlike {@link Arrays#asList(Object[])}, the list
	 * is modifiable and is not backed by the array.
	 */
	public static <E> ArrayList<E> list(E... array) {
		return new ArrayList<E>(Arrays.asList(array));
	}

	/**
	 * Return a list iterator for the specified array.
	 * <p>
	 * <code>Arrays.listIterator(Object[] array)</code>
	 */
	public static <E> ListIterator<E> listIterator(E... array) {
		return listIterator(array, 0);
	}

	/**
	 * Return a list iterator for the specified array
	 * starting at the specified position in the array.
	 * <p>
	 * <code>Arrays.listIterator(Object[] array, int index)</code>
	 */
	public static <E> ListIterator<E> listIterator(E[] array, int start) {
		return listIterator(array, start, array.length - start);
	}

	/**
	 * Return a list iterator for the specified array
	 * starting at the specified position in the array.
	 * <p>
	 * <code>Arrays.listIterator(Object[] array, int index, int length)</code>
	 */
	public static <E> ListIterator<E> listIterator(E[] array, int start, int length) {
		return new ArrayListIterator<E>(array, start, length);
	}


	// ********** move **********

	/**
	 * Move an element from the specified source index to the specified target
	 * index. Return the altered list.
	 * <p>
	 * <code>List.move(int targetIndex, int sourceIndex)</code>
	 */
	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex) {
		return (targetIndex == sourceIndex) ? list : move_(list, targetIndex, sourceIndex);
	}

	/**
	 * assume targetIndex != sourceIndex
	 */
	private static <E> List<E> move_(List<E> list, int targetIndex, int sourceIndex) {
		if (list instanceof RandomAccess) {
			// move elements, leaving the list in place
			E temp = list.get(sourceIndex);
			if (targetIndex < sourceIndex) {
				for (int i = sourceIndex; i-- > targetIndex; ) {
					list.set(i + 1, list.get(i));
				}
			} else {
				for (int i = sourceIndex; i < targetIndex; i++) {
					list.set(i, list.get(i + 1));
				}
			}
			list.set(targetIndex, temp);
		} else {
			// remove the element and re-add it at the target index
			list.add(targetIndex, list.remove(sourceIndex));
		}
		return list;
	}

	/**
	 * Move elements from the specified source index to the specified target
	 * index. Return the altered list.
	 * <p>
	 * <code>List.move(int targetIndex, int sourceIndex, int length)</code>
	 */
	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex, int length) {
		if ((targetIndex == sourceIndex) || (length == 0)) {
			return list;
		}
		if (length == 1) {
			return move_(list, targetIndex, sourceIndex);
		}
		if (list instanceof RandomAccess) {
			// move elements, leaving the list in place
			ArrayList<E> temp = new ArrayList<E>(list.subList(sourceIndex, sourceIndex + length));
			if (targetIndex < sourceIndex) {
				for (int i = sourceIndex; i-- > targetIndex; ) {
					list.set(i + length, list.get(i));
				}
			} else {
				for (int i = sourceIndex; i < targetIndex; i++) {
					list.set(i, list.get(i + length));
				}
			}
			for (int i = 0; i < length; i++) {
				list.set(targetIndex + i, temp.get(i));
			}
		} else {
			// remove the elements and re-add them at the target index
			list.addAll(targetIndex, removeElementsAtIndex(list, sourceIndex, length));
		}
		return list;
	}


	// ********** remove all **********

	/**
	 * Remove all the elements returned by the specified iterable
	 * from the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.removeAll(Iterable iterable)</code>
	 */
	public static boolean removeAll(Collection<?> collection, Iterable<?> iterable) {
		return removeAll(collection, iterable.iterator());
	}

	/**
	 * Remove all the elements returned by the specified iterable
	 * from the specified collection.
	 * Return whether the collection changed as a result.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Collection.removeAll(Iterable iterable)</code>
	 */
	public static boolean removeAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
		return removeAll(collection, iterable.iterator(), iterableSize);
	}

	/**
	 * Remove all the elements returned by the specified iterator
	 * from the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.removeAll(Iterator iterator)</code>
	 */
	public static boolean removeAll(Collection<?> collection, Iterator<?> iterator) {
		return iterator.hasNext() ? collection.removeAll(set(iterator)) : false;
	}

	/**
	 * Remove all the elements returned by the specified iterator
	 * from the specified collection.
	 * Return whether the collection changed as a result.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Collection.removeAll(Iterator iterator)</code>
	 */
	public static boolean removeAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
		return iterator.hasNext() ? collection.removeAll(set(iterator, iteratorSize)) : false;
	}

	/**
	 * Remove all the elements in the specified array
	 * from the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.removeAll(Object[] array)</code>
	 */
	public static boolean removeAll(Collection<?> collection, Object... array) {
		return (array.length == 0) ? false : collection.removeAll(set(array));
	}


	// ********** remove all occurrences **********

	/**
	 * Remove all occurrences of the specified element
	 * from the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.removeAllOccurrences(Object value)</code>
	 */
	public static boolean removeAllOccurrences(Collection<?> collection, Object value) {
		boolean modified = false;
		Iterator<?> stream = collection.iterator();
		if (value == null) {
			while (stream.hasNext()) {
				if (stream.next() == null) {
					stream.remove();
					modified = true;
				}
			}
		} else {
			while (stream.hasNext()) {
				if (value.equals(stream.next())) {
					stream.remove();
					modified = true;
				}
			}
		}
		return modified;
	}


	// ********** remove elements at index **********

	/**
	 * Remove the elements at the specified index.
	 * Return the removed elements.
	 * <p>
	 * <code>List.remove(int index, int length)</code>
	 */
	public static <E> ArrayList<E> removeElementsAtIndex(List<E> list, int index, int length) {
		List<E> subList = list.subList(index, index + length);
		ArrayList<E> result = new ArrayList<E>(subList);
		subList.clear();
		return result;
	}


	// ********** remove duplicate elements **********

	/**
	 * Remove any duplicate elements from the specified list,
	 * while maintaining the order.
	 * Return whether the list changed as a result.
	 */
	public static <E> boolean removeDuplicateElements(List<E> list) {
		int size = list.size();
		if ((size == 0) || (size == 1)) {
			return false;
		}
		return removeDuplicateElements(list, size);
	}

	/**
	 * assume list is non-empty
	 */
	static <E> boolean removeDuplicateElements(List<E> list, int size) {
		LinkedHashSet<E> temp = new LinkedHashSet<E>(size);		// take advantage of hashed look-up
		boolean modified = false;
		for (E item : list) {
			if ( ! temp.add(item)) {
				modified = true;  // duplicate item
			}
		}
		if (modified) {
			int i = 0;
			for (E e : temp) {
				list.set(i, e);
				i++;
			}
			int tempSize = temp.size();
			for (i = list.size(); i-- > tempSize; ) {
				list.remove(i);  // pull off the end
			}
		}
		return modified;
	}


	// ********** retain all **********

	/**
	 * Retain only the elements in the specified iterable
	 * in the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.retainAll(Iterable iterable)</code>
	 */
	public static boolean retainAll(Collection<?> collection, Iterable<?> iterable) {
		return retainAll(collection, iterable.iterator());
	}

	/**
	 * Retain only the elements in the specified iterable
	 * in the specified collection.
	 * Return whether the collection changed as a result.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Collection.retainAll(Iterable iterable)</code>
	 */
	public static boolean retainAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
		return retainAll(collection, iterable.iterator(), iterableSize);
	}

	/**
	 * Retain only the elements in the specified iterator
	 * in the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.retainAll(Iterator iterator)</code>
	 */
	public static boolean retainAll(Collection<?> collection, Iterator<?> iterator) {
		if (iterator.hasNext()) {
			return collection.retainAll(set(iterator));
		}
		if (collection.isEmpty()) {
			return false;
		}
		collection.clear();
		return true;
	}

	/**
	 * Retain only the elements in the specified iterator
	 * in the specified collection.
	 * Return whether the collection changed as a result.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Collection.retainAll(Iterator iterator)</code>
	 */
	public static boolean retainAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
		if (iterator.hasNext()) {
			return collection.retainAll(set(iterator, iteratorSize));
		}
		if (collection.isEmpty()) {
			return false;
		}
		collection.clear();
		return true;
	}

	/**
	 * Retain only the elements in the specified array
	 * in the specified collection.
	 * Return whether the collection changed as a result.
	 * <p>
	 * <code>Collection.retainAll(Object[] array)</code>
	 */
	public static boolean retainAll(Collection<?> collection, Object... array) {
		if (array.length > 0) {
			return collection.retainAll(set(array));
		}
		if (collection.isEmpty()) {
			return false;
		}
		collection.clear();
		return true;
	}


	// ********** reverse list **********

	/**
	 * Return a list with entries in reverse order from those
	 * returned by the specified iterable.
	 * <p>
	 * <code>Iterable.reverseList()</code>
	 */
	public static <E> ArrayList<E> reverseList(Iterable<? extends E> iterable) {
		return reverseList(iterable.iterator());
	}

	/**
	 * Return a list with entries in reverse order from those
	 * returned by the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.reverseList()</code>
	 */
	public static <E> ArrayList<E> reverseList(Iterable<? extends E> iterable, int iterableSize) {
		return reverseList(iterable.iterator(), iterableSize);
	}

	/**
	 * Return a list with entries in reverse order from those
	 * returned by the specified iterator.
	 * <p>
	 * <code>Iterator.reverseList()</code>
	 */
	public static <E> ArrayList<E> reverseList(Iterator<? extends E> iterator) {
		return (ArrayList<E>) reverse(list(iterator));
	}

	/**
	 * Return a list with entries in reverse order from those
	 * returned by the specified iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.reverseList()</code>
	 */
	public static <E> ArrayList<E> reverseList(Iterator<? extends E> iterator, int size) {
		return (ArrayList<E>) reverse(list(iterator, size));
	}


	// ********** rotate **********

	/**
	 * Return the list after it has been "rotated" by one position.
	 * <p>
	 * <code>List.rotate()</code>
	 */
	public static <E> List<E> rotate(List<E> list) {
		return rotate(list, 1);
	}


	// ********** set **********

	/**
	 * Return a set corresponding to the specified iterable.
	 * <p>
	 * <code>HashSet(Iterable iterable)</code>
	 */
	public static <E> HashSet<E> set(Iterable<? extends E> iterable) {
		return set(iterable.iterator());
	}

	/**
	 * Return a set corresponding to the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>HashSet(Iterable iterable)</code>
	 */
	public static <E> HashSet<E> set(Iterable<? extends E> iterable, int iterableSize) {
		return set(iterable.iterator(), iterableSize);
	}

	/**
	 * Return a set corresponding to the specified iterator.
	 * <p>
	 * <code>HashSet(Iterator iterator)</code>
	 */
	public static <E> HashSet<E> set(Iterator<? extends E> iterator) {
		return set(iterator, new HashSet<E>());
	}

	/**
	 * Return a set corresponding to the specified iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>HashSet(Iterator iterator)</code>
	 */
	public static <E> HashSet<E> set(Iterator<? extends E> iterator, int iteratorSize) {
		return set(iterator, new HashSet<E>(iteratorSize));
	}

	private static <E> HashSet<E> set(Iterator<? extends E> iterator, HashSet<E> set) {
		while (iterator.hasNext()) {
			set.add(iterator.next());
		}
		return set;
	}

	/**
	 * Return a set corresponding to the specified array.
	 * <p>
	 * <code>HashSet(Object[] array)</code>
	 */
	public static <E> HashSet<E> set(E... array) {
		HashSet<E> set = new HashSet<E>(array.length);
		for (int i = array.length; i-- > 0;) {
			set.add(array[i]);
		}
		return set;
	}


	// ********** singleton iterator **********

	/**
	 * Return an iterator that returns only the single,
	 * specified object.
	 * <p>
	 * <code>Object.toIterator()</code>
	 */
	public static <E> Iterator<E> singletonIterator(E value) {
		return new SingleElementIterator<E>(value);
	}

	/**
	 * Return a list iterator that returns only the single,
	 * specified object.
	 * <p>
	 * <code>Object.toListIterator()</code>
	 */
	public static <E> ListIterator<E> singletonListIterator(E value) {
		return new SingleElementListIterator<E>(value);
	}


	// ********** size **********

	/**
	 * Return the number of elements returned by the specified iterable.
	 * <p>
	 * <code>Iterable.size()</code>
	 */
	public static int size(Iterable<?> iterable) {
		return size(iterable.iterator());
	}

	/**
	 * Return the number of elements returned by the specified iterator.
	 * <p>
	 * <code>Iterator.size()</code>
	 */
	public static int size(Iterator<?> iterator) {
		int size = 0;
		while (iterator.hasNext()) {
			iterator.next();
			size++;
		}
		return size;
	}
	
	/**
	 * Return whether the specified iterable is empty
	 * (Shortcuts the iterator rather than calculating the entire size)
	 */
	public static boolean isEmpty(Iterable<?> iterable) {
		return isEmpty(iterable.iterator());
	}
	
	/**
	 * Return whether the specified iterator is empty
	 * (Shortcuts the iterator rather than calculating the entire size)
	 */
	public static boolean isEmpty(Iterator<?> iterator) {
		return ! iterator.hasNext();
	}
	
	
	// ********** sort **********

	/**
	 * Return an iterable containing the sorted elements of the specified iterable.
	 * <p>
	 * <code>Iterable.sort()</code>
	 */
	public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable) {
		return sort(iterable, null);
	}

	/**
	 * Return an iterable containing the sorted elements of the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.sort()</code>
	 */
	public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable, int iterableSize) {
		return sort(iterable, null, iterableSize);
	}

	/**
	 * Return an iterable containing the sorted elements of the specified iterable.
	 * <p>
	 * <code>Iterable.sort(Comparator comparator)</code>
	 */
	public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator) {
		return sort(list(iterable), comparator);
	}

	/**
	 * Return an iterable containing the sorted elements of the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.sort(Comparator comparator)</code>
	 */
	public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator, int iterableSize) {
		return sort(list(iterable, iterableSize), comparator);
	}

	/**
	 * Return the iterator after it has been "sorted".
	 * <p>
	 * <code>Iterator.sort()</code>
	 */
	public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator) {
		return sort(iterator, null);
	}

	/**
	 * Return the iterator after it has been "sorted".
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.sort()</code>
	 */
	public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator, int iteratorSize) {
		return sort(iterator, null, iteratorSize);
	}

	/**
	 * Return the iterator after it has been "sorted".
	 * <p>
	 * <code>Iterator.sort(Comparator comparator)</code>
	 */
	public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator) {
		return sort(list(iterator), comparator).listIterator();
	}

	/**
	 * Return the iterator after it has been "sorted".
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.sort(Comparator comparator)</code>
	 */
	public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {
		return sort(list(iterator, iteratorSize), comparator).listIterator();
	}


	// ********** sorted set **********

	/**
	 * Return a sorted set corresponding to the specified iterable.
	 * <p>
	 * <code>TreeSet(Iterable iterable)</code>
	 */
	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable) {
		return sortedSet(iterable.iterator());
	}

	/**
	 * Return a sorted set corresponding to the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>TreeSet(Iterable iterable)</code>
	 */
	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable, int iterableSize) {
		return sortedSet(iterable.iterator(), iterableSize);
	}

	/**
	 * Return a sorted set corresponding to the specified iterable
	 * and comparator.
	 * <p>
	 * <code>TreeSet(Iterable iterable, Comparator c)</code>
	 */
	public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator) {
		return sortedSet(iterable.iterator(), comparator);
	}

	/**
	 * Return a sorted set corresponding to the specified iterable
	 * and comparator.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>TreeSet(Iterable iterable, Comparator c)</code>
	 */
	public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator, int iterableSize) {
		return sortedSet(iterable.iterator(), comparator, iterableSize);
	}

	/**
	 * Return a sorted set corresponding to the specified iterator.
	 * <p>
	 * <code>TreeSet(Iterator iterator)</code>
	 */
	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator) {
		return sortedSet(iterator, null);
	}

	/**
	 * Return a sorted set corresponding to the specified iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>TreeSet(Iterator iterator)</code>
	 */
	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator, int iteratorSize) {
		return sortedSet(iterator, null, iteratorSize);
	}

	/**
	 * Return a sorted set corresponding to the specified iterator
	 * and comparator.
	 * <p>
	 * <code>TreeSet(Iterator iterator, Comparator c)</code>
	 */
	public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator) {
		return sortedSet(list(iterator), comparator);
	}

	/**
	 * Return a sorted set corresponding to the specified iterator
	 * and comparator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>TreeSet(Iterator iterator, Comparator c)</code>
	 */
	public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {
		return sortedSet(list(iterator, iteratorSize), comparator);
	}

	private static <E> TreeSet<E> sortedSet(List<E> list, Comparator<? super E> comparator) {
		TreeSet<E> sortedSet = new TreeSet<E>(comparator);
		sortedSet.addAll(list);
		return sortedSet;
	}

	/**
	 * Return a sorted set corresponding to the specified array.
	 * <p>
	 * <code>TreeSet(Object[] array)</code>
	 */
	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(E... array) {
		return sortedSet(array, null);
	}

	/**
	 * Return a sorted set corresponding to the specified array
	 * and comparator.
	 * <p>
	 * <code>TreeSet(Object[] array, Comparator c)</code>
	 */
	public static <E> TreeSet<E> sortedSet(E[] array, Comparator<? super E> comparator) {
		TreeSet<E> sortedSet = new TreeSet<E>(comparator);
		sortedSet.addAll(Arrays.asList(array));
		return sortedSet;
	}


	// ********** Old School Vector **********

	/**
	 * Return a vector corresponding to the specified iterable.
	 * This is useful for legacy code that requires a {@link Vector}.
	 * <p>
	 * <code>Vector(Iterable iterable)</code>
	 */
	public static <E> Vector<E> vector(Iterable<? extends E> iterable) {
		return vector(iterable.iterator());
	}

	/**
	 * Return a vector corresponding to the specified iterable.
	 * This is useful for legacy code that requires a {@link Vector}.
	 * <p>
	 * <code>Vector(Iterable iterable, int size)</code>
	 */
	public static <E> Vector<E> vector(Iterable<? extends E> iterable, int size) {
		return vector(iterable.iterator(), size);
	}

	/**
	 * Return a vector corresponding to the specified iterator.
	 * This is useful for legacy code that requires a {@link Vector}.
	 * <p>
	 * <code>Vector(Iterator iterator)</code>
	 */
	public static <E> Vector<E> vector(Iterator<? extends E> iterator) {
		return vector(iterator, new Vector<E>());
	}

	/**
	 * Return a vector corresponding to the specified iterator.
	 * This is useful for legacy code that requires a {@link Vector}.
	 * <p>
	 * <code>Vector(Iterator iterator, int size)</code>
	 */
	public static <E> Vector<E> vector(Iterator<? extends E> iterator, int size) {
		return vector(iterator, new Vector<E>(size));
	}

	private static <E> Vector<E> vector(Iterator<? extends E> iterator, Vector<E> v) {
		while (iterator.hasNext()) {
			v.addElement(iterator.next());
		}
		return v;
	}

	/**
	 * Return a vector corresponding to the specified array.
	 * This is useful for legacy code that requires a {@link Vector}.
	 * <p>
	 * <code>Vector(Object... array)</code>
	 */
	public static <E> Vector<E> vector(E... array) {
		Vector<E> v = new Vector<E>(array.length);
		for (E item : array) {
			v.addElement(item);
		}
		return v;
	}


	// ********** single-use Iterable **********

	/**
	 * Return a one-use {@link Iterable} for the specified {@link Iterator}.
	 * Throw an {@link IllegalStateException} if {@link Iterable#iterator()}
	 * is called more than once.
	 * As such, this utility should only be used in one-use situations, such as
	 * a foreach loop.
	 */
	public static <E> Iterable<E> iterable(Iterator<? extends E> iterator) {
		return new SingleUseIterable<E>(iterator);
	}

	/**
	 * This is a one-time use iterable that can return a single iterator.
	 * Once the iterator is returned the iterable is no longer valid.
	 * As such, this utility should only be used in one-time use situations,
	 * such as a 'for-each' loop.
	 */
	public static class SingleUseIterable<E> implements Iterable<E> {
		private Iterator<E> iterator;

		public SingleUseIterable(Iterator<? extends E> iterator) {
			super();
			if (iterator == null) {
				throw new NullPointerException();
			}
			this.iterator = new SuperIteratorWrapper<E>(iterator);
		}

		public Iterator<E> iterator() {
			if (this.iterator == null) {
				throw new IllegalStateException("This method has already been called."); //$NON-NLS-1$
			}
			Iterator<E> result = this.iterator;
			this.iterator = null;
			return result;
		}

		@Override
		public String toString() {
			return StringTools.buildToStringFor(this, this.iterator);
		}

	}


	// ********** java.util.Collections enhancements **********

	/**
	 * Return the destination list after the source list has been copied into it.
	 * @see Collections#copy(List, List)
	 */
	public static <E> List<E> copy(List<E> dest, List<? extends E> src) {
		Collections.copy(dest, src);
		return dest;
	}

	/**
	 * Return the list after it has been "filled".
	 * @see Collections#fill(List, Object)
	 */
	public static <E> List<E> fill(List<E> list, E value) {
		Collections.fill(list, value);
		return list;
	}

	/**
	 * Return the list after it has been "reversed".
	 * @see Collections#reverse(List)
	 */
	public static <E> List<E> reverse(List<E> list) {
		Collections.reverse(list);
		return list;
	}

	/**
	 * Return the list after it has been "rotated".
	 * @see Collections#rotate(List, int)
	 */
	public static <E> List<E> rotate(List<E> list, int distance) {
		Collections.rotate(list, distance);
		return list;
	}

	/**
	 * Return the list after it has been "shuffled".
	 * @see Collections#shuffle(List)
	 */
	public static <E> List<E> shuffle(List<E> list) {
		Collections.shuffle(list);
		return list;
	}

	/**
	 * Return the list after it has been "shuffled".
	 * @see Collections#shuffle(List, Random)
	 */
	public static <E> List<E> shuffle(List<E> list, Random random) {
		Collections.shuffle(list, random);
		return list;
	}

	/**
	 * Return the list after it has been "sorted".
	 * NB: The list is sorted in place as a side-effect.
	 * @see Collections#sort(List)
	 */
	public static <E extends Comparable<? super E>> List<E> sort(List<E> list) {
		Collections.sort(list);
		return list;
	}

	/**
	 * Return the list after it has been "sorted".
	 * NB: The list is sorted in place as a side-effect.
	 * @see Collections#sort(List, Comparator)
	 */
	public static <E> List<E> sort(List<E> list, Comparator<? super E> comparator) {
		Collections.sort(list, comparator);
		return list;
	}

	/**
	 * Return the list after the specified elements have been "swapped".
	 * @see Collections#swap(List, int, int)
	 */
	public static <E> List<E> swap(List<E> list, int i, int j) {
		Collections.swap(list, i, j);
		return list;
	}


	// ********** constructor **********

	/**
	 * Suppress default constructor, ensuring non-instantiability.
	 */
	private CollectionTools() {
		super();
		throw new UnsupportedOperationException();
	}

}
