/*******************************************************************************
 * 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.utility.internal;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;

/**
 * Array-related utility methods.
 */
public final class ArrayTools {
	public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
	public static final char[] EMPTY_CHAR_ARRAY = new char[0];
	public static final int[] EMPTY_INT_ARRAY = new int[0];

	// ********** instantiation **********

	/**
	 * Return a new array with the specified length
	 * and the same component type as the specified array.
	 * <p>
	 * <code>Arrays.newArray(Object[] array, int length)</code>
	 */
	public static <E> E[] newArray(E[] array, int length) {
		return newArray(componentType(array), length);
	}

	/**
	 * Return the specified array's component type, with appropriate support
	 * for generics.
	 */
	public static <E> Class<? extends E> componentType(E[] array) {
		Class<?> rawComponentType = array.getClass().getComponentType();
		@SuppressWarnings("unchecked")
		Class<? extends E> componentType = (Class<? extends E>) rawComponentType;
		return componentType;
	}

	/**
	 * Return a new array with the specified component type and length,
	 * with appropriate support for generics. The component type cannot be a
	 * primitive type.
	 */
	public static <E> E[] newArray(Class<? extends E> componentType, int length) {
		if (componentType.isPrimitive()) {
			throw new IllegalArgumentException("Array class cannot be primitive: " + componentType); //$NON-NLS-1$
		}
		return newArray_(componentType, length);
	}

	/**
	 * assume the component type is not a primitive class
	 */
	@SuppressWarnings("unchecked")
	private static <E> E[] newArray_(Class<? extends E> componentType, int length) {
		return (E[]) ((componentType == OBJECT_CLASS) ?
				new Object[length] :
				Array.newInstance(componentType, length));
	}
	private static final Class<Object> OBJECT_CLASS = Object.class;


	// ********** conversion **********

	/**
	 * Return an array corresponding to the specified iterable.
	 * <p>
	 * <code>Iterable.toArray()</code>
	 * @see Collection#toArray()
	 */
	public static Object[] array(Iterable<?> iterable) {
		return array(iterable.iterator());
	}

	/**
	 * Return an array corresponding to the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.toArray()</code>
	 * @see Collection#toArray()
	 */
	public static Object[] array(Iterable<?> iterable, int iterableSize) {
		return array(iterable.iterator(), iterableSize);
	}

	/**
	 * Return an array corresponding to the specified iterable;
	 * the runtime type of the returned array is that of the specified array.
	 * If the iterable 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 the iterable.
	 * <p>
	 * <code>Iterable.toArray(Object[])</code>
	 * @see Collection#toArray(Object[])
	 */
	public static <E> E[] array(Iterable<? extends E> iterable, E[] array) {
		return array(iterable.iterator(), array);
	}

	/**
	 * Return an array corresponding to the specified iterable;
	 * the runtime type of the returned array is that of the specified array.
	 * If the iterable 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 the iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Iterable.toArray(Object[])</code>
	 * @see Collection#toArray(Object[])
	 */
	public static <E> E[] array(Iterable<? extends E> iterable, int iterableSize, E[] array) {
		return array(iterable.iterator(), iterableSize, array);
	}

	/**
	 * Return an array corresponding to the specified iterator.
	 * <p>
	 * <code>Iterator.toArray()</code>
	 * @see Collection#toArray()
	 */
	public static Object[] array(Iterator<?> iterator) {
		return iterator.hasNext() ?
				CollectionTools.list(iterator).toArray() :
				EMPTY_OBJECT_ARRAY;
	}

	/**
	 * Return an array corresponding to the specified iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.toArray()</code>
	 * @see Collection#toArray()
	 */
	public static Object[] array(Iterator<?> iterator, int iteratorSize) {
		return iterator.hasNext() ?
				CollectionTools.list(iterator, iteratorSize).toArray() :
				EMPTY_OBJECT_ARRAY;
	}

	/**
	 * Return an array corresponding to the specified iterator;
	 * the runtime type of the returned array is that of the specified array.
	 * If the iterator 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 the iterator.
	 * <p>
	 * <code>Iterator.toArray(Object[])</code>
	 * @see Collection#toArray(Object[])
	 */
	public static <E> E[] array(Iterator<? extends E> iterator, E[] array) {
		return iterator.hasNext() ?
				CollectionTools.list(iterator).toArray(array) :
				emptyArray(array);
	}

	/**
	 * Return an array corresponding to the specified iterator;
	 * the runtime type of the returned array is that of the specified array.
	 * If the iterator 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 the iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Iterator.toArray(Object[])</code>
	 * @see Collection#toArray(Object[])
	 */
	public static <E> E[] array(Iterator<? extends E> iterator, int iteratorSize, E[] array) {
		return iterator.hasNext() ?
				CollectionTools.list(iterator, iteratorSize).toArray(array) :
				emptyArray(array);
	}

	/**
	 * If the specified array is empty, return it;
	 * otherwise, set its first element to null.
	 * @see Collection#toArray(Object[])
	 */
	private static <E> E[] emptyArray(E[] array) {
		return (array.length == 0) ? array : clearFirst(array);
	}

	/**
	 * Set the specified array's first element to null and and return the array.
	 * Assume the array length > 0.
	 */
	private static <E> E[] clearFirst(E[] array) {
		array[0] = null;
		return array;
	}


	// ********** add **********

	/**
	 * Return a new array containing the elements in the
	 * specified array followed by the specified object to be added.
	 * <p>
	 * <code>Arrays.add(Object[] array, Object o)</code>
	 */
	public static <E> E[] add(E[] array, E value) {
		int len = array.length;
		E[] result = newArray(array, len + 1);
		if (len > 0) {
			System.arraycopy(array, 0, result, 0, len);
		}
		result[len] = value;
		return result;
	}

	/**
	 * Return a new array containing the elements in the
	 * specified array with the specified object added at the specified index.
	 * <p>
	 * <code>Arrays.add(Object[] array, int index, Object o)</code>
	 */
	public static <E> E[] add(E[] array, int index, E value) {
		int len = array.length;
		E[] result = newArray(array, len + 1);
		if (index > 0) {
			System.arraycopy(array, 0, result, 0, index);
		}
		result[index] = value;
		if (index < len) {
			System.arraycopy(array, index, result, index + 1, len - index);
		}
		return result;
	}

	/**
	 * Return a new array containing the elements in the
	 * specified array followed by the specified value to be added.
	 * <p>
	 * <code>Arrays.add(char[] array, char value)</code>
	 */
	public static char[] add(char[] array, char value) {
		int len = array.length;
		char[] result = new char[len + 1];
		if (len > 0) {
			System.arraycopy(array, 0, result, 0, len);
		}
		result[len] = value;
		return result;
	}

	/**
	 * Return a new array containing the elements in the
	 * specified array with the specified value added at the specified index.
	 * <p>
	 * <code>Arrays.add(char[] array, int index, char value)</code>
	 */
	public static char[] add(char[] array, int index, char value) {
		int len = array.length;
		char[] result = new char[len + 1];
		if (index > 0) {
			System.arraycopy(array, 0, result, 0, index);
		}
		result[index] = value;
		if (index < len) {
			System.arraycopy(array, index, result, index + 1, len - index);
		}
		return result;
	}

	/**
	 * Return a new array containing the elements in the
	 * specified array followed by the specified value to be added.
	 * <p>
	 * <code>Arrays.add(int[] array, int value)</code>
	 */
	public static int[] add(int[] array, int value) {
		int len = array.length;
		int[] result = new int[len + 1];
		if (len > 0) {
			System.arraycopy(array, 0, result, 0, len);
		}
		result[len] = value;
		return result;
	}

	/**
	 * Return a new array containing the elements in the
	 * specified array with the specified value added at the specified index.
	 * <p>
	 * <code>Arrays.add(int[] array, int index, int value)</code>
	 */
	public static int[] add(int[] array, int index, int value) {
		int len = array.length;
		int[] result = new int[len + 1];
		if (index > 0) {
			System.arraycopy(array, 0, result, 0, index);
		}
		result[index] = value;
		if (index < len) {
			System.arraycopy(array, index, result, index + 1, len - index);
		}
		return result;
	}


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

	/**
	 * Return an array containing the elements in the
	 * specified array followed by the elements
	 * in the specified collection.
	 *<p>
	 * <code>Arrays.addAll(Object[] array, Collection collection)</code>
	 */
	public static <E> E[] addAll(E[] array, Collection<? extends E> collection) {
		return addAll(array, collection, collection.size());
	}

	/**
	 * check collection size
	 */
	private static <E> E[] addAll(E[] array, Collection<? extends E> collection, int collectionSize) {
		return (collectionSize == 0) ? array : addAll_(array, collection, collectionSize);
	}

	/**
	 * assume the collection is non-empty
	 */
	private static <E> E[] addAll_(E[] array, Collection<? extends E> collection) {
		return addAll_(array, collection, collection.size());
	}

	/**
	 * assume collection size > zero
	 */
	private static <E> E[] addAll_(E[] array, Collection<? extends E> collection, int collectionSize) {
		return addAll(array, collection, array.length, collectionSize);
	}

	/**
	 * assume collection size > zero; check array length
	 */
	private static <E> E[] addAll(E[] array, Collection<? extends E> collection, int arrayLength, int collectionSize) {
		return (arrayLength == 0) ?
				collection.toArray(newArray(array, collectionSize)) :
				addAll_(array, collection, arrayLength, collectionSize);
	}

	/**
	 * assume array length and collection size > zero
	 */
	private static <E> E[] addAll_(E[] array, Collection<? extends E> collection, int arrayLength, int collectionSize) {
		E[] result = newArray(array, arrayLength + collectionSize);
		System.arraycopy(array, 0, result, 0, arrayLength);
		int i = arrayLength;
		for (E element : collection) {
			result[i++] = element;
		}
		return result;
	}

	/**
	 * Return an array containing the elements in the
	 * specified array followed by the elements
	 * in the specified iterable.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, Iterable iterable)</code>
	 */
	public static <E> E[] addAll(E[] array, Iterable<? extends E> iterable) {
		return addAll(array, iterable.iterator());
	}

	/**
	 * Return an array containing the elements in the
	 * specified array followed by the elements
	 * in the specified iterable.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, Iterable iterable)</code>
	 */
	public static <E> E[] addAll(E[] array, Iterable<? extends E> iterable, int iterableSize) {
		return addAll(array, iterable.iterator(), iterableSize);
	}

	/**
	 * Return an array containing the elements in the
	 * specified array followed by the elements
	 * in the specified iterator.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, Iterator iterator)</code>
	 */
	public static <E> E[] addAll(E[] array, Iterator<? extends E> iterator) {
		return iterator.hasNext() ? addAll_(array, CollectionTools.list(iterator)) : array;
	}

	/**
	 * Return an array containing the elements in the
	 * specified array followed by the elements
	 * in the specified iterator.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, Iterator iterator)</code>
	 */
	public static <E> E[] addAll(E[] array, Iterator<? extends E> iterator, int iteratorSize) {
		return iterator.hasNext() ? addAll_(array, CollectionTools.list(iterator, iteratorSize)) : array;
	}

	/**
	 * Return an array containing the elements in the
	 * specified array 1 followed by the elements
	 * in the specified array 2.
	 * <p>
	 * <code>Arrays.addAll(Object[] array1, Object[] array2)</code>
	 */
	public static <E> E[] addAll(E[] array1, E... array2) {
		return addAll(array1, array2, array2.length);
	}

	/**
	 * check array 2 length
	 */
	private static <E> E[] addAll(E[] array1, E[] array2, int array2Length) {
		return (array2Length == 0) ? array1 : addAll_(array1, array2, array2Length);
	}

	/**
	 * assume array 2 length > 0
	 */
	private static <E> E[] addAll_(E[] array1, E[] array2, int array2Length) {
		return addAll(array1, array2, array1.length, array2Length);
	}

	/**
	 * assume array 2 length > 0; check array 1 length
	 */
	private static <E> E[] addAll(E[] array1, E[] array2, int array1Length, int array2Length) {
		return (array1Length == 0) ? array2 : addAll_(array1, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0
	 */
	private static <E> E[] addAll_(E[] array1, E[] array2, int array1Length, int array2Length) {
		E[] result = newArray(array1, array1Length + array2Length);
		System.arraycopy(array1, 0, result, 0, array1Length);
		System.arraycopy(array2, 0, result, array1Length, array2Length);
		return result;
	}

	/**
	 * Return an array containing the elements in the
	 * first specified array with the objects in the second
	 * specified array added at the specified index.
	 * <p>
	 * <code>Arrays.addAll(Object[] array1, int index, Object[] array2)</code>
	 */
	public static <E> E[] addAll(E[] array1, int index, E... array2) {
		return addAll(array1, index, array2, array2.length);
	}

	/**
	 * check array 2 length
	 */
	private static <E> E[] addAll(E[] array1, int index, E[] array2, int array2Length) {
		return (array2Length == 0) ? array1 : addAll_(array1, index, array2, array2Length);
	}

	/**
	 * assume array 2 length > 0
	 */
	private static <E> E[] addAll_(E[] array1, int index, E[] array2, int array2Length) {
		return addAll(array1, index, array2, array1.length, array2Length);
	}

	/**
	 * assume array 2 length > 0; check array 1 length
	 */
	private static <E> E[] addAll(E[] array1, int index, E[] array2, int array1Length, int array2Length) {
		return (array1Length == 0) ?
					array2 :
					(index == array1Length) ?  // 'array2' added to end of 'array1'
						addAll_(array1, array2, array1Length, array2Length) :
						addAll_(array1, index, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0 and index != array 1 length
	 */
	private static <E> E[] addAll_(E[] array1, int index, E[] array2, int array1Length, int array2Length) {
		E[] result = newArray(array1, array1Length + array2Length);
		System.arraycopy(array1, 0, result, 0, index);
		System.arraycopy(array2, 0, result, index, array2Length);
		System.arraycopy(array1, index, result, index + array2Length, array1Length - index);
		return result;
	}

	/**
	 * Return an array containing the elements in the
	 * specified array with the elements
	 * in the specified collection inserted at the specified index.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, int index, Collection c)</code>
	 */
	public static <E> E[] addAll(E[] array, int index, Collection<? extends E> collection) {
		return addAll(array, index, collection, collection.size());
	}

	/**
	 * check collection size
	 */
	private static <E> E[] addAll(E[] array, int index, Collection<? extends E> collection, int collectionSize) {
		return (collectionSize == 0) ? array : addAll_(array, index, collection, collectionSize);
	}

	/**
	 * assume collection size > 0
	 */
	private static <E> E[] addAll_(E[] array, int index, Collection<? extends E> collection, int collectionSize) {
		return addAll(array, index, collection, array.length, collectionSize);
	}

	/**
	 * assume collection size > 0; check array length
	 */
	private static <E> E[] addAll(E[] array, int index, Collection<? extends E> collection, int arrayLength, int collectionSize) {
		if (arrayLength == 0) {
			if (index == 0) {
				return collection.toArray(newArray(array, collectionSize));
			}
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return (index == arrayLength) ?  // 'collection' added to end of 'array'
				addAll_(array, collection, arrayLength, collectionSize) :
				addAll_(array, index, collection, arrayLength, collectionSize);
	}

	/**
	 * assume array length and collection size > 0 and index != array length
	 */
	private static <E> E[] addAll_(E[] array, int index, Collection<? extends E> collection, int arrayLength, int collectionSize) {
		E[] result = newArray(array, arrayLength + collectionSize);
		System.arraycopy(array, 0, result, 0, index);
		int i = index;
		for (E item : collection) {
			result[i++] = item;
		}
		System.arraycopy(array, index, result, index + collectionSize, arrayLength - index);
		return result;
	}

	/**
	 * Return an array containing the elements in the
	 * specified array with the elements
	 * in the specified iterable inserted at the specified index.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, int index, Iterable iterable)</code>
	 */
	public static <E> E[] addAll(E[] array, int index, Iterable<? extends E> iterable) {
		return addAll(array, index, iterable.iterator());
	}

	/**
	 * Return an array containing the elements in the
	 * specified array with the elements
	 * in the specified iterable inserted at the specified index.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, int index, Iterable iterable)</code>
	 */
	public static <E> E[] addAll(E[] array, int index, Iterable<? extends E> iterable, int iterableSize) {
		return addAll(array, index, iterable.iterator(), iterableSize);
	}

	/**
	 * Return an array containing the elements in the
	 * specified array with the elements
	 * in the specified iterator inserted at the specified index.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, int index, Iterator iterator)</code>
	 */
	public static <E> E[] addAll(E[] array, int index, Iterator<? extends E> iterator) {
		return iterator.hasNext() ? addAll_(array, index, CollectionTools.list(iterator)) : array;
	}

	/**
	 * Return an array containing the elements in the
	 * specified array with the elements
	 * in the specified iterator inserted at the specified index.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Arrays.addAll(Object[] array, int index, Iterator iterator)</code>
	 */
	public static <E> E[] addAll(E[] array, int index, Iterator<? extends E> iterator, int iteratorSize) {
		return iterator.hasNext() ? addAll_(array, index, CollectionTools.list(iterator, iteratorSize)) : array;
	}

	/**
	 * assume collection is non-empty
	 */
	private static <E> E[] addAll_(E[] array, int index, Collection<? extends E> collection) {
		return addAll_(array, index, collection, collection.size());
	}

	/**
	 * Return an array containing the elements in the
	 * specified array 1 followed by the elements
	 * in the specified array 2.
	 * <p>
	 * <code>Arrays.addAll(char[] array1, char[] array2)</code>
	 */
	public static char[] addAll(char[] array1, char... array2) {
		return addAll(array1, array2, array2.length);
	}

	/**
	 * check array 2 length
	 */
	private static char[] addAll(char[] array1, char[] array2, int array2Length) {
		return (array2Length == 0) ? array1 : addAll_(array1, array2, array2Length);
	}

	/**
	 * assume array 2 length > 0
	 */
	private static char[] addAll_(char[] array1, char[] array2, int array2Length) {
		return addAll(array1, array2, array1.length, array2Length);
	}

	/**
	 * assume array 2 length > 0; check array 1 length
	 */
	private static char[] addAll(char[] array1, char[] array2, int array1Length, int array2Length) {
		return (array1Length == 0) ? array2 : addAll_(array1, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0
	 */
	private static char[] addAll_(char[] array1, char[] array2, int array1Length, int array2Length) {
		char[] result = new char[array1Length + array2Length];
		System.arraycopy(array1, 0, result, 0, array1Length);
		System.arraycopy(array2, 0, result, array1Length, array2Length);
		return result;
	}

	/**
	 * Return an array containing the elements in the
	 * first specified array with the objects in the second
	 * specified array added at the specified index.
	 * <p>
	 * <code>Arrays.add(char[] array1, int index, char[] array2)</code>
	 */
	public static char[] addAll(char[] array1, int index, char... array2) {
		return addAll(array1, index, array2, array2.length);
	}

	/**
	 * check array 2 length
	 */
	private static char[] addAll(char[] array1, int index, char[] array2, int array2Length) {
		return (array2Length == 0) ? array1 : addAll_(array1, index, array2, array2Length);
	}

	/**
	 * assume array 2 length > 0
	 */
	private static char[] addAll_(char[] array1, int index, char[] array2, int array2Length) {
		return addAll(array1, index, array2, array1.length, array2Length);
	}

	/**
	 * assume array 2 length > 0; check array 1 length
	 */
	private static char[] addAll(char[] array1, int index, char[] array2, int array1Length, int array2Length) {
		return (array1Length == 0) ?
					array2 :
					(index == array1Length) ?  // 'array2' added to end of 'array1'
						addAll_(array1, array2, array1Length, array2Length) :
						addAll_(array1, index, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0 and index != array 1 length
	 */
	private static char[] addAll_(char[] array1, int index, char[] array2, int array1Length, int array2Length) {
		char[] result = new char[array1Length + array2Length];
		System.arraycopy(array1, 0, result, 0, index);
		System.arraycopy(array2, 0, result, index, array2Length);
		System.arraycopy(array1, index, result, index + array2Length, array1Length - index);
		return result;
	}

	/**
	 * Return an array containing the elements in the
	 * specified array 1 followed by the elements
	 * in the specified array 2.
	 * <p>
	 * <code>Arrays.addAll(int[] array1, int[] array2)</code>
	 */
	public static int[] addAll(int[] array1, int... array2) {
		return addAll(array1, array2, array2.length);
	}

	/**
	 * check array 2 length
	 */
	private static int[] addAll(int[] array1, int[] array2, int array2Length) {
		return (array2Length == 0) ? array1 : addAll_(array1, array2, array2Length);
	}

	/**
	 * assume array 2 length > 0
	 */
	private static int[] addAll_(int[] array1, int[] array2, int array2Length) {
		return addAll(array1, array2, array1.length, array2Length);
	}

	/**
	 * assume array 2 length > 0; check array 1 length
	 */
	private static int[] addAll(int[] array1, int[] array2, int array1Length, int array2Length) {
		return (array1Length == 0) ? array2 : addAll_(array1, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0
	 */
	private static int[] addAll_(int[] array1, int[] array2, int array1Length, int array2Length) {
		int[] result = new int[array1Length + array2Length];
		System.arraycopy(array1, 0, result, 0, array1Length);
		System.arraycopy(array2, 0, result, array1Length, array2Length);
		return result;
	}

	/**
	 * Return an array containing the elements in the
	 * first specified array with the objects in the second
	 * specified array added at the specified index.
	 * <p>
	 * <code>Arrays.add(int[] array1, int index, int[] array2)</code>
	 */
	public static int[] addAll(int[] array1, int index, int... array2) {
		return addAll(array1, index, array2, array2.length);
	}

	/**
	 * check array 2 length
	 */
	private static int[] addAll(int[] array1, int index, int[] array2, int array2Length) {
		return (array2Length == 0) ? array1 : addAll_(array1, index, array2, array2Length);
	}

	/**
	 * assume array 2 length > 0
	 */
	private static int[] addAll_(int[] array1, int index, int[] array2, int array2Length) {
		return addAll(array1, index, array2, array1.length, array2Length);
	}

	/**
	 * assume array 2 length > 0; check array 1 length
	 */
	private static int[] addAll(int[] array1, int index, int[] array2, int array1Length, int array2Length) {
		return (array1Length == 0) ?
					array2 :
					(index == array1Length) ?  // 'array2' added to end of 'array1'
						addAll_(array1, array2, array1Length, array2Length) :
						addAll_(array1, index, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0 and index != array 1 length
	 */
	private static int[] addAll_(int[] array1, int index, int[] array2, int array1Length, int array2Length) {
		int[] result = new int[array1Length + array2Length];
		System.arraycopy(array1, 0, result, 0, index);
		System.arraycopy(array2, 0, result, index, array2Length);
		System.arraycopy(array1, index, result, index + array2Length, array1Length - index);
		return result;
	}


	// ********** clear **********

	/**
	 * Return an empty array with the same component type as the specified array.
	 * <p>
	 * <code>Arrays.clear(Object[] array)</code>
	 */
	public static <E> E[] clear(E[] array) {
		return (array.length == 0) ? array : newArray(array, 0);
	}


	// ********** concatenate **********

	/**
	 * Return an array containing all the elements in all the
	 * specified arrays, concatenated in the specified order.
	 * This is useful for building constant arrays out of other constant arrays.
	 * <p>
	 * <code>Arrays.concatenate(Object[]... arrays)</code>
	 */
	public static <E> E[] concatenate(E[]... arrays) {
		int len = 0;
		for (E[] array : arrays) {
			len += array.length;
		}
		E[] result = newArray(arrays[0], len);
		if (len == 0) {
			return result;
		}
		int current = 0;
		for (E[] array : arrays) {
			int arrayLength = array.length;
			if (arrayLength > 0) {
				System.arraycopy(array, 0, result, current, arrayLength);
				current += arrayLength;
			}
		}
		return result;
	}

	/**
	 * Return an array containing all the elements in  all the
	 * specified arrays, concatenated in the specified order.
	 * This is useful for building constant arrays out other constant arrays.
	 * <p>
	 * <code>Arrays.concatenate(char[]... arrays)</code>
	 */
	public static char[] concatenate(char[]... arrays) {
		int len = 0;
		for (char[] array : arrays) {
			len += array.length;
		}
		if (len == 0) {
			return EMPTY_CHAR_ARRAY;
		}
		char[] result = new char[len];
		int current = 0;
		for (char[] array : arrays) {
			int arrayLength = array.length;
			if (arrayLength != 0) {
				System.arraycopy(array, 0, result, current, arrayLength);
				current += arrayLength;
			}
		}
		return result;
	}

	/**
	 * Return an array containing all the elements in  all the
	 * specified arrays, concatenated in the specified order.
	 * This is useful for building constant arrays out other constant arrays.
	 * <p>
	 * <code>Arrays.concatenate(int[]... arrays)</code>
	 */
	public static int[] concatenate(int[]... arrays) {
		int len = 0;
		for (int[] array : arrays) {
			len += array.length;
		}
		if (len == 0) {
			return EMPTY_INT_ARRAY;
		}
		int[] result = new int[len];
		int current = 0;
		for (int[] array : arrays) {
			int arrayLength = array.length;
			if (arrayLength != 0) {
				System.arraycopy(array, 0, result, current, arrayLength);
				current += arrayLength;
			}
		}
		return result;
	}


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

	/**
	 * Return whether the specified array contains the
	 * specified element.
	 * <p>
	 * <code>Arrays.contains(Object[] array, Object o)</code>
	 */
	public static boolean contains(Object[] array, Object value) {
		return contains(array, value, array.length);
	}

	/**
	 * check array length
	 */
	private static boolean contains(Object[] array, Object value, int arrayLength) {
		return (arrayLength == 0) ? false : contains_(array, value, arrayLength);
	}

	/**
	 * assume array length > 0
	 */
	public static boolean contains_(Object[] array, Object value, int arrayLength) {
		if (value == null) {
			for (int i = arrayLength; i-- > 0; ) {
				if (array[i] == null) {
					return true;
				}
			}
		} else {
			for (int i = arrayLength; i-- > 0; ) {
				if (value.equals(array[i])) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Return whether the specified array contains the
	 * specified element.
	 * <p>
	 * <code>Arrays.contains(char[] array, char value)</code>
	 */
	public static boolean contains(char[] array, char value) {
		return contains(array, value, array.length);
	}

	/**
	 * check array length
	 */
	private static boolean contains(char[] array, char value, int arrayLength) {
		return (arrayLength == 0) ? false : contains_(array, value, arrayLength);
	}

	/**
	 * assume array length > 0
	 */
	private static boolean contains_(char[] array, char value, int arrayLength) {
		for (int i = arrayLength; i-- > 0; ) {
			if (array[i] == value) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Return whether the specified array contains the
	 * specified element.
	 * <p>
	 * <code>Arrays.contains(int[] array, int value)</code>
	 */
	public static boolean contains(int[] array, int value) {
		return contains(array, value, array.length);
	}

	/**
	 * check array length
	 */
	private static boolean contains(int[] array, int value, int arrayLength) {
		return (arrayLength == 0) ? false : contains_(array, value, arrayLength);
	}

	/**
	 * assume array length > 0
	 */
	private static boolean contains_(int[] array, int value, int arrayLength) {
		for (int i = arrayLength; i-- > 0; ) {
			if (array[i] == value) {
				return true;
			}
		}
		return false;
	}


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

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

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

	/**
	 * Return whether the specified array contains all of the
	 * elements in the specified iterator.
	 * <p>
	 * <code>Arrays.containsAll(Object[] array, Iterator iterator)</code>
	 */
	public static boolean containsAll(Object[] array, Iterator<?> iterator) {
		// use hashed lookup
		HashSet<Object> set = CollectionTools.set(array);
		while (iterator.hasNext()) {
			if ( ! set.contains(iterator.next())) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Return whether the specified array 1 contains all of the
	 * elements in the specified array 2.
	 * <p>
	 * <code>Arrays.containsAll(Object[] array1, Object[] array2)</code>
	 */
	public static boolean containsAll(Object[] array1, Object... array2) {
		// use hashed lookup
		HashSet<Object> set = CollectionTools.set(array1);
		for (int i = array2.length; i-- > 0; ) {
			if ( ! set.contains(array2[i])) {
				return false;
			}
		}
		return true;
	}

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

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


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

	/**
	 * Return the index of the first elements in the specified
	 * arrays that are different, beginning at the end.
	 * If the arrays are identical, return -1.
	 * If the arrays are different sizes, return the index of the
	 * last element in the longer array.
	 * Use the elements' {@link Object#equals()} method to compare the
	 * elements.
	 */
	public static int diffEnd(Object[] array1, Object[] array2) {
		int len1 = array1.length;
		int len2 = array2.length;
		if (len1 != len2) {
			return Math.max(len1, len2) - 1;
		}
		for (int i = len1 - 1; i > -1; i--) {
			Object o = array1[i];
			if (o == null) {
				if (array2[i] != null) {
					return i;
				}
			} else {
				if ( ! o.equals(array2[i])) {
					return i;
				}
			}
		}
		return -1;
	}

	/**
	 * 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()} method to compare the
	 * elements.
	 * @see #diffStart(Object[], Object[])
	 * @see #diffEnd(Object[], Object[])
	 */
	public static Range diffRange(Object[] array1, Object[] array2) {
		int end = diffEnd(array1, array2);
		if (end == -1) {
			// the lists are identical, the start is the size of the two lists
			return new Range(array1.length, end);
		}
		// the lists are different, calculate the start of the range
		return new Range(diffStart(array1, array2), end);
	}

	/**
	 * Return the index of the first elements in the specified
	 * arrays that are different. If the arrays are identical, return
	 * the size of the two arrays (i.e. one past the last index).
	 * If the arrays are different sizes and all the elements in
	 * the shorter array match their corresponding elements in
	 * the longer array, return the size of the shorter array
	 * (i.e. one past the last index of the shorter array).
	 * Use the elements' {@link Object#equals()} method to compare the
	 * elements.
	 */
	public static int diffStart(Object[] array1, Object[] array2) {
		int end = Math.min(array1.length, array2.length);
		for (int i = 0; i < end; i++) {
			Object o = array1[i];
			if (o == null) {
				if (array2[i] != null) {
					return i;
				}
			} else {
				if ( ! o.equals(array2[i])) {
					return i;
				}
			}
		}
		return end;
	}


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

	/**
	 * Return the index of the first elements in the specified
	 * arrays that are different, beginning at the end.
	 * If the arrays are identical, return -1.
	 * If the arrays are different sizes, return the index of the
	 * last element in the longer array.
	 * Use object identity to compare the elements.
	 */
	public static int identityDiffEnd(Object[] array1, Object[] array2) {
		int len1 = array1.length;
		int len2 = array2.length;
		if (len1 != len2) {
			return Math.max(len1, len2) - 1;
		}
		for (int i = len1 - 1; i > -1; i--) {
			if (array1[i] != array2[i]) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 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.
	 * @see #identityDiffStart(Object[], Object[])
	 * @see #identityDiffEnd(Object[], Object[])
	 */
	public static Range identityDiffRange(Object[] array1, Object[] array2) {
		int end = identityDiffEnd(array1, array2);
		if (end == -1) {
			// the lists are identical, the start is the size of the two lists
			return new Range(array1.length, end);
		}
		// the lists are different, calculate the start of the range
		return new Range(identityDiffStart(array1, array2), end);
	}

	/**
	 * Return the index of the first elements in the specified
	 * arrays that are different. If the arrays are identical, return
	 * the size of the two arrays (i.e. one past the last index).
	 * If the arrays are different sizes and all the elements in
	 * the shorter array match their corresponding elements in
	 * the longer array, return the size of the shorter array
	 * (i.e. one past the last index of the shorter array).
	 * Use object identity to compare the elements.
	 */
	public static int identityDiffStart(Object[] array1, Object[] array2) {
		int end = Math.min(array1.length, array2.length);
		for (int i = 0; i < end; i++) {
			if (array1[i] != array2[i]) {
				return i;
			}
		}
		return end;
	}


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

	/**
	 * Return whether the specified arrays contain the same elements.
	 * <p>
	 * <code>Arrays.identical(Object[] array1, Object[] array2)</code>
	 */
	public static boolean elementsAreIdentical(Object[] array1, Object[] array2) {
		if (array1 == array2) {
			return true;
		}
		if (array1 == null || array2 == null) {
			return false;
		}
		int length = array1.length;
		if (array2.length != length) {
			return false;
		}
		for (int i = length; i-- > 0; ) {
			if (array1[i] != array2[i]) {
				return false;
			}
		}
		return true;
	}


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

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified array,
	 * or return -1 if there is no such index.
	 * <p>
	 * <code>Arrays.indexOf(Object[] array, Object o)</code>
	 */
	public static int indexOf(Object[] array, Object value) {
		int len = array.length;
		if (value == null) {
			for (int i = 0; i < len; i++) {
				if (array[i] == null) {
					return i;
				}
			}
		} else {
			for (int i = 0; i < len; i++) {
				if (value.equals(array[i])) {
					return i;
				}
			}
		}
		return -1;
	}

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified array,
	 * or return -1 if there is no such index.
	 * <p>
	 * <code>Arrays.identityIndexOf(Object[] array, Object o)</code>
	 */
	public static int identityIndexOf(Object[] array, Object value) {
		int len = array.length;
		for (int i = 0; i < len; i++) {
			if (array[i] == value) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified array,
	 * or return -1 if there is no such index.
	 * <p>
	 * <code>Arrays.indexOf(char[] array, char value)</code>
	 */
	public static int indexOf(char[] array, char value) {
		int len = array.length;
		for (int i = 0; i < len; i++) {
			if (array[i] == value) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * Return the index of the first occurrence of the
	 * specified element in the specified array,
	 * or return -1 if there is no such index.
	 * <p>
	 * <code>Arrays.indexOf(int[] array, int value)</code>
	 */
	public static int indexOf(int[] array, int value) {
		int len = array.length;
		for (int i = 0; i < len; i++) {
			if (array[i] == value) {
				return i;
			}
		}
		return -1;
	}


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

	/**
	 * Return the maximum index of where the specified comparable object
	 * should be inserted into the specified sorted array and still keep
	 * the array sorted.
	 */
	public static <E extends Comparable<? super E>> int insertionIndexOf(E[] sortedArray, Comparable<E> value) {
		int len = sortedArray.length;
		for (int i = 0; i < len; i++) {
			if (value.compareTo(sortedArray[i]) < 0) {
				return i;
			}
		}
		return len;
	}

	/**
	 * Return the maximum index of where the specified comparable object
	 * should be inserted into the specified sorted array and still keep
	 * the array sorted.
	 */
	public static <E> int insertionIndexOf(E[] sortedArray, E value, Comparator<? super E> comparator) {
		int len = sortedArray.length;
		for (int i = 0; i < len; i++) {
			if (comparator.compare(value, sortedArray[i]) < 0) {
				return i;
			}
		}
		return len;
	}


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

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified array;
	 * return -1 if there is no such index.
	 * <p>
	 * <code>Arrays.lastIndexOf(Object[] array, Object o)</code>
	 */
	public static int lastIndexOf(Object[] array, Object value) {
		int len = array.length;
		if (value == null) {
			for (int i = len; i-- > 0; ) {
				if (array[i] == null) {
					return i;
				}
			}
		} else {
			for (int i = len; i-- > 0; ) {
				if (value.equals(array[i])) {
					return i;
				}
			}
		}
		return -1;
	}

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified array,
	 * or return -1 if there is no such index.
	 * <p>
	 * <code>Arrays.lastIndexOf(char[] array, char value)</code>
	 */
	public static int lastIndexOf(char[] array, char value) {
		for (int i = array.length; i-- > 0; ) {
			if (array[i] == value) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * Return the index of the last occurrence of the
	 * specified element in the specified array,
	 * or return -1 if there is no such index.
	 * <p>
	 * <code>Arrays.lastIndexOf(int[] array, int value)</code>
	 */
	public static int lastIndexOf(int[] array, int value) {
		for (int i = array.length; i-- > 0; ) {
			if (array[i] == value) {
				return i;
			}
		}
		return -1;
	}


	// ********** min/max **********

	/**
	 * Return the character from the specified array with the minimum value.
	 * <p>
	 * <code>Arrays.min(char[] array)</code>
	 */
	public static char min(char... array) {
		int len = array.length;
		if (len == 0) {
			throw new IndexOutOfBoundsException();
		}
		int last = len - 1;
		char min = array[last];
		for (int i = last; i-- > 0; ) {
			char c = array[i];
			if (c < min) {
				min = c;
			}
		}
		return min;
	}

	/**
	 * Return the integer from the specified array with the minimum value.
	 * <p>
	 * <code>Arrays.min(int[] array)</code>
	 */
	public static int min(int... array) {
		int len = array.length;
		if (len == 0) {
			throw new IndexOutOfBoundsException();
		}
		int last = len - 1;
		int min = array[last];
		for (int i = last; i-- > 0; ) {
			int x = array[i];
			if (x < min) {
				min = x;
			}
		}
		return min;
	}

	/**
	 * Return the character from the specified array with the maximum value.
	 * <p>
	 * <code>Arrays.max(char[] array)</code>
	 */
	public static char max(char... array) {
		int len = array.length;
		if (len == 0) {
			throw new IndexOutOfBoundsException();
		}
		int last = len - 1;
		char max = array[last];
		for (int i = last; i-- > 0; ) {
			char c = array[i];
			if (c > max) {
				max = c;
			}
		}
		return max;
	}

	/**
	 * Return the integer from the specified array with the maximum value.
	 * <p>
	 * <code>Arrays.max(int[] array)</code>
	 */
	public static int max(int... array) {
		int len = array.length;
		if (len == 0) {
			throw new IndexOutOfBoundsException();
		}
		int last = len - 1;
		int max = array[last];
		for (int i = last; i-- > 0; ) {
			int x = array[i];
			if (x > max) {
				max = x;
			}
		}
		return max;
	}


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

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

	/**
	 * assume target index != source index
	 */
	private static <E> E[] move_(E[] array, int targetIndex, int sourceIndex) {
		E temp = array[sourceIndex];
		if (targetIndex < sourceIndex) {
			System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex);
		} else {
			System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex);
		}
		array[targetIndex] = temp;
		return array;
	}

	/**
	 * Move elements from the specified source index to the specified target
	 * index. Return the altered array.
	 * <p>
	 * <code>Arrays.move(Object[] array, int targetIndex, int sourceIndex, int length)</code>
	 */
	public static <E> E[] move(E[] array, int targetIndex, int sourceIndex, int length) {
		if ((targetIndex == sourceIndex) || (length == 0)) {
			return array;
		}
		if (length == 1) {
			return move_(array, targetIndex, sourceIndex);
		}
		E[] temp = newArray(array, length);
		System.arraycopy(array, sourceIndex, temp, 0, length);
		if (targetIndex < sourceIndex) {
			System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex);
		} else {
			System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex);
		}
		System.arraycopy(temp, 0, array, targetIndex, length);
		return array;
	}

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

	/**
	 * assume targetIndex != sourceIndex
	 */
	private static int[] move_(int[] array, int targetIndex, int sourceIndex) {
		int temp = array[sourceIndex];
		if (targetIndex < sourceIndex) {
			System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex);
		} else {
			System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex);
		}
		array[targetIndex] = temp;
		return array;
	}

	/**
	 * Move elements from the specified source index to the specified target
	 * index. Return the altered array.
	 * <p>
	 * <code>Arrays.move(int[] array, int targetIndex, int sourceIndex, int length)</code>
	 */
	public static int[] move(int[] array, int targetIndex, int sourceIndex, int length) {
		if ((targetIndex == sourceIndex) || (length == 0)) {
			return array;
		}
		if (length == 1) {
			return move_(array, targetIndex, sourceIndex);
		}
		int[] temp = new int[length];
		System.arraycopy(array, sourceIndex, temp, 0, length);
		if (targetIndex < sourceIndex) {
			System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex);
		} else {
			System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex);
		}
		System.arraycopy(temp, 0, array, targetIndex, length);
		return array;
	}

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

	/**
	 * assume targetIndex != sourceIndex
	 */
	private static char[] move_(char[] array, int targetIndex, int sourceIndex) {
		char temp = array[sourceIndex];
		if (targetIndex < sourceIndex) {
			System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex);
		} else {
			System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex);
		}
		array[targetIndex] = temp;
		return array;
	}

	/**
	 * Move elements from the specified source index to the specified target
	 * index. Return the altered array.
	 * <p>
	 * <code>Arrays.move(char[] array, int targetIndex, int sourceIndex, int length)</code>
	 */
	public static char[] move(char[] array, int targetIndex, int sourceIndex, int length) {
		if ((targetIndex == sourceIndex) || (length == 0)) {
			return array;
		}
		if (length == 1) {
			return move_(array, targetIndex, sourceIndex);
		}
		char[] temp = new char[length];
		System.arraycopy(array, sourceIndex, temp, 0, length);
		if (targetIndex < sourceIndex) {
			System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex);
		} else {
			System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex);
		}
		System.arraycopy(temp, 0, array, targetIndex, length);
		return array;
	}


	// ********** remove **********

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified element removed.
	 * <p>
	 * <code>Arrays.remove(Object[] array, Object value)</code>
	 */
	public static <E> E[] remove(E[] array, Object value) {
		return removeElementAtIndex(array, indexOf(array, value));
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified element removed.
	 * <p>
	 * <code>Arrays.remove(char[] array, char value)</code>
	 */
	public static char[] remove(char[] array, char value) {
		return removeElementAtIndex(array, indexOf(array, value));
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified element removed.
	 * <p>
	 * <code>Arrays.remove(int[] array, int value)</code>
	 */
	public static int[] remove(int[] array, int value) {
		return removeElementAtIndex(array, indexOf(array, value));
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the first element removed.
	 * <p>
	 * <code>Arrays.removeFirst(Object[] array)</code>
	 */
	public static <E> E[] removeFirst(E[] array) {
		return removeElementAtIndex(array, 0);
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the first element removed.
	 * <p>
	 * <code>Arrays.removeFirst(char[] array)</code>
	 */
	public static char[] removeFirst(char[] array) {
		return removeElementAtIndex(array, 0);
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the first element removed.
	 * <p>
	 * <code>Arrays.removeFirst(int[] array)</code>
	 */
	public static int[] removeFirst(int[] array) {
		return removeElementAtIndex(array, 0);
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the last element removed.
	 * <p>
	 * <code>Arrays.removeLast(Object[] array)</code>
	 */
	public static <E> E[] removeLast(E[] array) {
		return removeElementAtIndex(array, array.length - 1);
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the last element removed.
	 * <p>
	 * <code>Arrays.removeLast(char[] array)</code>
	 */
	public static char[] removeLast(char[] array) {
		return removeElementAtIndex(array, array.length - 1);
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the last element removed.
	 * <p>
	 * <code>Arrays.removeLast(int[] array)</code>
	 */
	public static int[] removeLast(int[] array) {
		return removeElementAtIndex(array, array.length - 1);
	}


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

	/**
	 * Remove from the specified array all the elements in
	 * the specified iterable and return the result.
	 * <p>
	 * <code>Arrays.removeAll(Object[] array, Iterable iterable)</code>
	 */
	public static <E> E[] removeAll(E[] array, Iterable<?> iterable) {
		return removeAll(array, iterable.iterator());
	}

	/**
	 * Remove from the specified array all the elements in
	 * the specified iterable and return the result.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Arrays.removeAll(Object[] array, Iterable iterable)</code>
	 */
	public static <E> E[] removeAll(E[] array, Iterable<?> iterable, int iterableSize) {
		return removeAll(array, iterable.iterator(), iterableSize);
	}

	/**
	 * Remove from the specified array all the elements in
	 * the specified iterator and return the result.
	 * <p>
	 * <code>Arrays.removeAll(Object[] array, Iterator iterator)</code>
	 */
	public static <E> E[] removeAll(E[] array, Iterator<?> iterator) {
		// convert to a set to take advantage of hashed look-up
		return iterator.hasNext() ? removeAll_(array, CollectionTools.set(iterator)) : array;
	}

	/**
	 * Remove from the specified array all the elements in
	 * the specified iterator and return the result.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Arrays.removeAll(Object[] array, Iterator iterator)</code>
	 */
	public static <E> E[] removeAll(E[] array, Iterator<?> iterator, int iteratorSize) {
		// convert to a set to take advantage of hashed look-up
		return iterator.hasNext() ? removeAll_(array, CollectionTools.set(iterator, iteratorSize)) : array;
	}

	/**
	 * Remove from the specified array all the elements in
	 * the specified collection and return the result.
	 * <p>
	 * <code>Arrays.removeAll(Object[] array, Collection collection)</code>
	 */
	public static <E> E[] removeAll(E[] array, Collection<?> collection) {
		return collection.isEmpty() ? array : removeAll_(array, collection);
	}

	/**
	 * assume collection is non-empty
	 */
	private static <E> E[] removeAll_(E[] array, Collection<?> collection) {
		return removeAll(array, collection, array.length);
	}

	/**
	 * assume collection is non-empty; check array length
	 */
	private static <E> E[] removeAll(E[] array, Collection<?> collection, int arrayLength) {
		return (arrayLength == 0) ? array : removeAll_(array, collection, arrayLength);
	}

	/**
	 * assume collection is non-empty and array length > 0
	 */
	private static <E> E[] removeAll_(E[] array, Collection<?> collection, int arrayLength) {
		// build the indices of the elements that are to remain
		int[] indices = new int[arrayLength];
		int j = 0;
		for (int i = 0; i < arrayLength; i++) {
			if ( ! collection.contains(array[i])) {
				indices[j++] = i;
			}
		}
		if (j == arrayLength) {
			return array;  // nothing was removed
		}
		E[] result = newArray(array, j);
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array[indices[i]];
		}
		return result;
	}

	/**
	 * Remove from the first specified array all the elements in
	 * the second specified array and return the result.
	 * <p>
	 * <code>Arrays.removeAll(Object[] array1, Object[] array2)</code>
	 */
	public static <E> E[] removeAll(E[] array1, Object... array2) {
		// convert to a set to take advantage of hashed look-up
		return (array2.length == 0) ? array1 : removeAll_(array1, CollectionTools.set(array2));
	}

	/**
	 * Remove from the first specified array all the elements in
	 * the second specified array and return the result.
	 * <p>
	 * <code>Arrays#removeAll(char[] array1, char[] array2)</code>
	 */
	public static char[] removeAll(char[] array1, char... array2) {
		if (array2.length == 0) {
			return array1;
		}
		int array1Length = array1.length;
		if (array1Length == 0) {
			return array1;
		}
		int[] indices = new int[array1Length];
		int j = 0;
		for (int i = 0; i < array1Length; i++) {
			if ( ! contains(array2, array1[i])) {
				indices[j++] = i;
			}
		}
		if (j == array1Length) {
			return array1;  // nothing was removed
		}
		char[] result = new char[j];
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array1[indices[i]];
		}
		return result;
	}

	/**
	 * Remove from the first specified array all the elements in
	 * the second specified array and return the result.
	 * <p>
	 * <code>Arrays#removeAll(int[] array1, int[] array2)</code>
	 */
	public static int[] removeAll(int[] array1, int... array2) {
		if (array2.length == 0) {
			return array1;
		}
		int array1Length = array1.length;
		if (array1Length == 0) {
			return array1;
		}
		int[] indices = new int[array1Length];
		int j = 0;
		for (int i = 0; i < array1Length; i++) {
			if ( ! contains(array2, array1[i])) {
				indices[j++] = i;
			}
		}
		if (j == array1Length) {
			return array1;  // nothing was removed
		}
		int[] result = new int[j];
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array1[indices[i]];
		}
		return result;
	}


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

	/**
	 * Remove from the specified array all occurrences of
	 * the specified element and return the result.
	 * <p>
	 * <code>Arrays.removeAllOccurrences(Object[] array, Object value)</code>
	 */
	public static <E> E[] removeAllOccurrences(E[] array, Object value) {
		int arrayLength = array.length;
		if (arrayLength == 0) {
			return array;
		}
		int[] indices = new int[arrayLength];
		int j = 0;
		if (value == null) {
			for (int i = arrayLength; i-- > 0; ) {
				if (array[i] != null) {
					indices[j++] = i;
				}
			}
		} else {
			for (int i = array.length; i-- > 0; ) {
				if ( ! value.equals(array[i])) {
					indices[j++] = i;
				}
			}
		}
		if (j == arrayLength) {
			return array;  // nothing was removed
		}
		E[] result = newArray(array, j);
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array[indices[i]];
		}
		return result;
	}

	/**
	 * Remove from the specified array all occurrences of
	 * the specified element and return the result.
	 * <p>
	 * <code>Arrays.removeAllOccurrences(char[] array, char value)</code>
	 */
	public static char[] removeAllOccurrences(char[] array, char value) {
		int arrayLength = array.length;
		if (arrayLength == 0) {
			return array;
		}
		int[] indices = new int[arrayLength];
		int j = 0;
		for (int i = arrayLength; i-- > 0; ) {
			if (array[i] != value) {
				indices[j++] = i;
			}
		}
		if (j == arrayLength) {
			return array;  // nothing was removed
		}
		char[] result = new char[j];
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array[indices[i]];
		}
		return result;
	}

	/**
	 * Remove from the specified array all occurrences of
	 * the specified element and return the result.
	 * <p>
	 * <code>Arrays.removeAllOccurrences(int[] array, int value)</code>
	 */
	public static int[] removeAllOccurrences(int[] array, int value) {
		int arrayLength = array.length;
		if (arrayLength == 0) {
			return array;
		}
		int[] indices = new int[arrayLength];
		int j = 0;
		for (int i = arrayLength; i-- > 0; ) {
			if (array[i] != value) {
				indices[j++] = i;
			}
		}
		if (j == arrayLength) {
			return array;  // nothing was removed
		}
		int[] result = new int[j];
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array[indices[i]];
		}
		return result;
	}


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

	/**
	 * Remove any duplicate elements from the specified array,
	 * while maintaining the order.
	 */
	public static <E> E[] removeDuplicateElements(E... array) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		ArrayList<E> temp = CollectionTools.list(array);
		return CollectionTools.removeDuplicateElements(temp, len) ?
					temp.toArray(newArray(array, temp.size())) :
					array;
	}


	// ********** remove element at index **********

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified element removed.
	 * <p>
	 * <code>Arrays.removeElementAtIndex(Object[] array, int index)</code>
	 */
	public static <E> E[] removeElementAtIndex(E[] array, int index) {
		return removeElementsAtIndex(array, index, 1);
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified element removed.
	 * <p>
	 * <code>Arrays.removeElementAtIndex(char[] array, int index)</code>
	 */
	public static char[] removeElementAtIndex(char[] array, int index) {
		return removeElementsAtIndex(array, index, 1);
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified element removed.
	 * <p>
	 * <code>Arrays.removeElementAtIndex(int[] array, int index)</code>
	 */
	public static int[] removeElementAtIndex(int[] array, int index) {
		return removeElementsAtIndex(array, index, 1);
	}


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

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified elements removed.
	 * <p>
	 * <code>Arrays.removeElementsAtIndex(Object[] array, int index, int length)</code>
	 */
	public static <E> E[] removeElementsAtIndex(E[] array, int index, int length) {
		if (length == 0) {
			return array;
		}
		int arrayLength = array.length;
		int newLength = arrayLength - length;
		E[] result = newArray(array, newLength);
		if ((newLength == 0) && (index == 0)) {
			return result;  // performance tweak
		}
		if (index != 0) {
			System.arraycopy(array, 0, result, 0, index);
		}
		int length2 = newLength - index;
		if (length2 != 0) {
			System.arraycopy(array, index + length, result, index, length2);
		}
		return result;
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified elements removed.
	 * <p>
	 * <code>Arrays.removeElementsAtIndex(char[] array, int index, int length)
	 */
	public static char[] removeElementsAtIndex(char[] array, int index, int length) {
		if (length == 0) {
			return array;
		}
		int arrayLength = array.length;
		int newLength = arrayLength - length;
		if ((newLength == 0) && (index == 0)) {
			return EMPTY_CHAR_ARRAY;  // performance tweak
		}
		char[] result = new char[newLength];
		if (index != 0) {
			System.arraycopy(array, 0, result, 0, index);
		}
		int length2 = newLength - index;
		if (length2 != 0) {
			System.arraycopy(array, index + length, result, index, length2);
		}
		return result;
	}

	/**
	 * Return a new array that contains the elements in the
	 * specified array with the specified elements removed.
	 * <p>
	 * <code>Arrays.removeElementsAtIndex(int[] array, int index, int length)
	 */
	public static int[] removeElementsAtIndex(int[] array, int index, int length) {
		if (length == 0) {
			return array;
		}
		int arrayLength = array.length;
		int newLength = arrayLength - length;
		if ((newLength == 0) && (index == 0)) {
			return EMPTY_INT_ARRAY;  // performance tweak
		}
		int[] result = new int[newLength];
		if (index != 0) {
			System.arraycopy(array, 0, result, 0, index);
		}
		int length2 = newLength - index;
		if (length2 != 0) {
			System.arraycopy(array, index + length, result, index, length2);
		}
		return result;
	}


	// ********** replace all **********

	/**
	 * Replace all occurrences of the specified old value with
	 * the specified new value. Return the altered array.
	 * <p>
	 * <code>Arrays.replaceAll(Object[] array, Object oldValue, Object newValue)</code>
	 */
	public static <E> E[] replaceAll(E[] array, Object oldValue, E newValue) {
		if (oldValue == null) {
			for (int i = array.length; i-- > 0; ) {
				if (array[i] == null) {
					array[i] = newValue;
				}
			}
		} else {
			for (int i = array.length; i-- > 0; ) {
				if (oldValue.equals(array[i])) {
					array[i] = newValue;
				}
			}
		}
		return array;
	}

	/**
	 * Replace all occurrences of the specified old value with
	 * the specified new value. Return the altered array.
	 *<p>
	 * <code> Arrays.replaceAll(int[] array, int oldValue, int newValue)</code>
	 */
	public static int[] replaceAll(int[] array, int oldValue, int newValue) {
		for (int i = array.length; i-- > 0; ) {
			if (array[i] == oldValue) {
				array[i] = newValue;
			}
		}
		return array;
	}

	/**
	 * Replace all occurrences of the specified old value with
	 * the specified new value. Return the altered array.
	 * <p>
	 * <code>Arrays.replaceAll(char[] array, char oldValue, char newValue)</code>
	 */
	public static char[] replaceAll(char[] array, char oldValue, char newValue) {
		for (int i = array.length; i-- > 0; ) {
			if (array[i] == oldValue) {
				array[i] = newValue;
			}
		}
		return array;
	}


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

	/**
	 * Retain in the specified array all the elements in
	 * the specified iterable and return the result.
	 * <p>
	 * <code>Arrays.retainAll(Object[] array, Iterable iterable)</code>
	 */
	public static <E> E[] retainAll(E[] array, Iterable<?> iterable) {
		int arrayLength = array.length;
		return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterable.iterator());
	}

	/**
	 * Retain in the specified array all the elements in
	 * the specified iterable and return the result.
	 * The specified iterable size is a performance hint.
	 * <p>
	 * <code>Arrays.retainAll(Object[] array, Iterable iterable)</code>
	 */
	public static <E> E[] retainAll(E[] array, Iterable<?> iterable, int iterableSize) {
		int arrayLength = array.length;
		return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterable.iterator(), iterableSize);
	}

	/**
	 * Retain in the specified array all the elements in
	 * the specified iterator and return the result.
	 * <p>
	 * <code>Arrays.retainAll(Object[] array, Iterator iterator)</code>
	 */
	public static <E> E[] retainAll(E[] array, Iterator<?> iterator) {
		int arrayLength = array.length;
		return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterator);
	}

	/**
	 * Retain in the specified array all the elements in
	 * the specified iterator and return the result.
	 * The specified iterator size is a performance hint.
	 * <p>
	 * <code>Arrays.retainAll(Object[] array, Iterator iterator)</code>
	 */
	public static <E> E[] retainAll(E[] array, Iterator<?> iterator, int iteratorSize) {
		int arrayLength = array.length;
		return (arrayLength == 0) ? array : retainAll(array, arrayLength, iterator, iteratorSize);
	}

	/**
	 * assume array length > 0
	 */
	private static <E> E[] retainAll(E[] array, int arrayLength, Iterator<?> iterator) {
		return iterator.hasNext() ?
				retainAll_(array, CollectionTools.set(iterator), arrayLength) :
				newArray(array, 0);
	}

	/**
	 * assume array length > 0
	 */
	private static <E> E[] retainAll(E[] array, int arrayLength, Iterator<?> iterator, int iteratorSize) {
		return iterator.hasNext() ?
				retainAll_(array, CollectionTools.set(iterator, iteratorSize), arrayLength) :
				newArray(array, 0);
	}

	/**
	 * Retain in the specified array all the elements in
	 * the specified collection and return the result.
	 * <p>
	 * <code>Arrays.retainAll(Object[] array, Collection collection)</code>
	 */
	public static <E> E[] retainAll(E[] array, Collection<?> collection) {
		int arrayLength = array.length;
		return (arrayLength == 0) ? array : retainAll(array, collection, arrayLength);
	}

	/**
	 * assume array length > 0
	 */
	private static <E> E[] retainAll(E[] array, Collection<?> collection, int arrayLength) {
		return collection.isEmpty() ?
				newArray(array, 0) :
				retainAll_(array, collection, arrayLength);
	}

	/**
	 * assume collection is non-empty and array length > 0
	 */
	private static <E> E[] retainAll_(E[] array, Collection<?> collection, int arrayLength) {
		int[] indices = new int[arrayLength];
		int j = 0;
		for (int i = 0; i < arrayLength; i++) {
			if (collection.contains(array[i])) {
				indices[j++] = i;
			}
		}
		if (j == arrayLength) {
			return array;  // everything was retained
		}
		E[] result = newArray(array, j);
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array[indices[i]];
		}
		return result;
	}

	/**
	 * Remove from the first specified array all the elements in
	 * the second specified array and return the result.
	 * <p>
	 * <code>Arrays.retainAll(Object[] array1, Object[] array2)</code>
	 */
	public static <E> E[] retainAll(E[] array1, Object[] array2) {
		int array1Length = array1.length;
		return (array1Length == 0) ?
				array1 :
				(array2.length == 0) ?
					newArray(array1, 0) :
					retainAll(array1, CollectionTools.set(array2), array1Length);
	}

	/**
	 * Remove from the first specified array all the elements in
	 * the second specified array and return the result.
	 * <p>
	 * <code>Arrays.retainAll(char[] array1, char[] array2)</code>
	 */
	public static char[] retainAll(char[] array1, char... array2) {
		int array1Length = array1.length;
		return (array1Length == 0) ? array1 : retainAll(array1, array2, array1Length);
	}

	/**
	 * assume array 1 length > 0
	 */
	private static char[] retainAll(char[] array1, char[] array2, int array1Length) {
		int array2Length = array2.length;
		return (array2Length == 0) ? EMPTY_CHAR_ARRAY : retainAll(array1, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0
	 */
	private static char[] retainAll(char[] array1, char[] array2, int array1Length, int array2Length) {
		int[] indices = new int[array1Length];
		int j = 0;
		for (int i = 0; i < array1Length; i++) {
			if (contains_(array2, array1[i], array2Length)) {
				indices[j++] = i;
			}
		}
		if (j == array1Length) {
			return array1;  // everything was retained
		}
		char[] result = new char[j];
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array1[indices[i]];
		}
		return result;
	}

	/**
	 * Remove from the first specified array all the elements in
	 * the second specified array and return the result.
	 * <p>
	 * <code>Arrays.retainAll(int[] array1, int[] array2)</code>
	 */
	public static int[] retainAll(int[] array1, int... array2) {
		int array1Length = array1.length;
		return (array1Length == 0) ? array1 : retainAll(array1, array2, array1Length);
	}

	/**
	 * assume array 1 length > 0
	 */
	private static int[] retainAll(int[] array1, int[] array2, int array1Length) {
		int array2Length = array2.length;
		return (array2Length == 0) ? EMPTY_INT_ARRAY : retainAll(array1, array2, array1Length, array2Length);
	}

	/**
	 * assume both array lengths > 0
	 */
	private static int[] retainAll(int[] array1, int[] array2, int array1Length, int array2Length) {
		int[] indices = new int[array1Length];
		int j = 0;
		for (int i = 0; i < array1Length; i++) {
			if (contains_(array2, array1[i], array2Length)) {
				indices[j++] = i;
			}
		}
		if (j == array1Length) {
			return array1;  // everything was retained
		}
		int[] result = new int[j];
		int resultLength = result.length;
		for (int i = 0; i < resultLength; i++) {
			result[i] = array1[indices[i]];
		}
		return result;
	}


	// ********** reverse **********

	/**
	 * Return the array, reversed.
	 * <p>
	 * <code>Arrays.reverse(Object... array)</code>
	 */
	public static <E> E[] reverse(E... array) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		for (int i = 0, mid = len >> 1, j = len - 1; i < mid; i++, j--) {
			swap(array, i, j);
		}
		return array;
	}

	/**
	 * Return the array, reversed.
	 * <p>
	 * <code>Arrays.reverse(char... array)</code>
	 */
	public static char[] reverse(char... array) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		for (int i = 0, mid = len >> 1, j = len - 1; i < mid; i++, j--) {
			swap(array, i, j);
		}
		return array;
	}

	/**
	 * Return the array, reversed.
	 * <p>
	 * <code>Arrays.reverse(int... array)</code>
	 */
	public static int[] reverse(int... array) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		for (int i = 0, mid = len >> 1, j = len - 1; i < mid; i++, j--) {
			swap(array, i, j);
		}
		return array;
	}


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

	/**
	 * Return the rotated array after rotating it one position.
	 * <p>
	 * <code>Arrays.rotate(Object[] array)</code>
	 */
	public static <E> E[] rotate(E... array) {
		return rotate(array, 1);
	}

	/**
	 * Return the rotated array after rotating it the specified distance.
	 * <p>
	 * <code>Arrays.rotate(Object[] array, int distance)</code>
	 */
	public static <E> E[] rotate(E[] array, int distance) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		distance = distance % len;
		if (distance < 0) {
			distance += len;
		}
		if (distance == 0) {
			return array;
		}
		for (int cycleStart = 0, nMoved = 0; nMoved != len; cycleStart++) {
			E displaced = array[cycleStart];
			int i = cycleStart;
			do {
				i += distance;
				if (i >= len) {
					i -= len;
				}
				E temp = array[i];
				array[i] = displaced;
				displaced = temp;
				nMoved ++;
			} while (i != cycleStart);
		}
		return array;
	}

	/**
	 * Return the rotated array after rotating it one position.
	 * <p>
	 * <code>Arrays.rotate(char[] array)</code>
	 */
	public static char[] rotate(char... array) {
		return rotate(array, 1);
	}

	/**
	 * Return the rotated array after rotating it the specified distance.
	 * <p>
	 * <code>Arrays.rotate(char[] array, int distance)</code>
	 */
	public static char[] rotate(char[] array, int distance) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		distance = distance % len;
		if (distance < 0) {
			distance += len;
		}
		if (distance == 0) {
			return array;
		}
		for (int cycleStart = 0, nMoved = 0; nMoved != len; cycleStart++) {
			char displaced = array[cycleStart];
			int i = cycleStart;
			do {
				i += distance;
				if (i >= len) {
					i -= len;
				}
				char temp = array[i];
				array[i] = displaced;
				displaced = temp;
				nMoved ++;
			} while (i != cycleStart);
		}
		return array;
	}

	/**
	 * Return the rotated array after rotating it one position.
	 * <p>
	 * <code>Arrays.rotate(int[] array)</code>
	 */
	public static int[] rotate(int... array) {
		return rotate(array, 1);
	}

	/**
	 * Return the rotated array after rotating it the specified distance.
	 * <p>
	 * <code>Arrays.rotate(int[] array, int distance)</code>
	 */
	public static int[] rotate(int[] array, int distance) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		distance = distance % len;
		if (distance < 0) {
			distance += len;
		}
		if (distance == 0) {
			return array;
		}
		for (int cycleStart = 0, nMoved = 0; nMoved != len; cycleStart++) {
			int displaced = array[cycleStart];
			int i = cycleStart;
			do {
				i += distance;
				if (i >= len) {
					i -= len;
				}
				int temp = array[i];
				array[i] = displaced;
				displaced = temp;
				nMoved ++;
			} while (i != cycleStart);
		}
		return array;
	}


	// ********** shuffle **********

	private static final Random RANDOM = new Random();

	/**
	 * Return the array after "shuffling" it.
	 * <p>
	 * <code>Arrays.shuffle(Object... array)</code>
	 */
	public static <E> E[] shuffle(E... array) {
		return shuffle(array, RANDOM);
	}

	/**
	 * Return the array after "shuffling" it.
	 * <p>
	 * <code>Arrays.shuffle(Object[] array, Random r)</code>
	 */
	public static <E> E[] shuffle(E[] array, Random random) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		for (int i = len; i-- > 0; ) {
			swap(array, i, random.nextInt(len));
		}
		return array;
	}

	/**
	 * Return the array after "shuffling" it.
	 * <p>
	 * <code>Arrays.shuffle(char... array)</code>
	 */
	public static char[] shuffle(char... array) {
		return shuffle(array, RANDOM);
	}

	/**
	 * Return the array after "shuffling" it.
	 * <p>
	 * <code>Arrays.shuffle(char[] array, Random r)</code>
	 */
	public static char[] shuffle(char[] array, Random random) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		for (int i = len; i-- > 0; ) {
			swap(array, i, random.nextInt(len));
		}
		return array;
	}

	/**
	 * Return the array after "shuffling" it.
	 * <p>
	 * <code>Arrays.shuffle(int... array)</code>
	 */
	public static int[] shuffle(int... array) {
		return shuffle(array, RANDOM);
	}

	/**
	 * Return the array after "shuffling" it.
	 * <p>
	 * <code>Arrays.shuffle(int[] array, Random r)</code>
	 */
	public static int[] shuffle(int[] array, Random random) {
		int len = array.length;
		if ((len == 0) || (len == 1)) {
			return array;
		}
		for (int i = len; i-- > 0; ) {
			swap(array, i, random.nextInt(len));
		}
		return array;
	}


	// ********** sub-array **********

	/**
	 * Return a sub-array of the specified array with elements copied from
	 * the specified range. The "from" index is inclusive; the "to" index is exclusive.
	 * <p>
	 * <code>Arrays.subArray(E[] array, int fromIndex, int toIndex)</code>
	 */
	public static <E> E[] subArray(E[] array, int fromIndex, int toIndex) {
		int len = toIndex - fromIndex;
		E[] result = newArray(array, len);
		if (len > 0) {
			System.arraycopy(array, fromIndex, result, 0, len);
		}
		return result;
	}

	/**
	 * Return a sub-array of the specified array with elements copied from
	 * the specified range. The "from" index is inclusive; the "to" index is exclusive.
	 * <p>
	 * <code>Arrays.subArray(int[] array, int fromIndex, int toIndex)</code>
	 */
	public static int[] subArray(int[] array, int fromIndex, int toIndex) {
		int len = toIndex - fromIndex;
		if (len == 0) {
			return EMPTY_INT_ARRAY;
		}
		int[] result = new int[len];
		System.arraycopy(array, fromIndex, result, 0, len);
		return result;
	}

	/**
	 * Return a sub-array of the specified array with elements copied from
	 * the specified range. The "from" index is inclusive; the "to" index is exclusive.
	 * <p>
	 * <code>
	 * Arrays.subArray(char[] array, int fromIndex, int toIndex)</code>
	 * </code>
	 */
	public static char[] subArray(char[] array, int fromIndex, int toIndex) {
		int len = toIndex - fromIndex;
		if (len == 0) {
			return EMPTY_CHAR_ARRAY;
		}
		char[] result = new char[len];
		System.arraycopy(array, fromIndex, result, 0, len);
		return result;
	}


	// ********** swap **********

	/**
	 * Return the array after the specified elements have been "swapped".
	 * <p>
	 * <code>Arrays.swap(Object[] array, int i, int j)</code>
	 */
	public static <E> E[] swap(E[] array, int i, int j) {
		return (i == j) ? array : swap_(array, i, j);
	}

	/**
	 * assume the indices are different
	 */
	private static <E> E[] swap_(E[] array, int i, int j) {
		E temp = array[i];
		array[i] = array[j];
		array[j] = temp;
		return array;
	}

	/**
	 * Return the array after the specified elements have been "swapped".
	 * <p>
	 * <code>Arrays.swap(char[] array, int i, int j)</code>
	 */
	public static char[] swap(char[] array, int i, int j) {
		return (i == j) ? array : swap_(array, i, j);
	}

	/**
	 * assume the indices are different
	 */
	private static char[] swap_(char[] array, int i, int j) {
		char temp = array[i];
		array[i] = array[j];
		array[j] = temp;
		return array;
	}

	/**
	 * Return the array after the specified elements have been "swapped".
	 * <p>
	 * <code>Arrays.swap(int[] array, int i, int j)</code>
	 */
	public static int[] swap(int[] array, int i, int j) {
		return (i == j) ? array : swap_(array, i, j);
	}

	/**
	 * assume the indices are different
	 */
	private static int[] swap_(int[] array, int i, int j) {
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
		return array;
	}


	// ********** Arrays enhancements **********

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(boolean[], boolean)
	 */
	public static boolean[] fill(boolean[] array, boolean value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(boolean[], int, int, boolean)
	 */
	public static boolean[] fill(boolean[] array, int fromIndex, int toIndex, boolean value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(byte[], byte)
	 */
	public static byte[] fill(byte[] array, byte value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(byte[], int, int, byte)
	 */
	public static byte[] fill(byte[] array, int fromIndex, int toIndex, byte value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(char[], char)
	 */
	public static char[] fill(char[] array, char value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(char[], int, int, char)
	 */
	public static char[] fill(char[] array, int fromIndex, int toIndex, char value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(double[], double)
	 */
	public static double[] fill(double[] array, double value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(double[], int, int, double)
	 */
	public static double[] fill(double[] array, int fromIndex, int toIndex, double value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(float[], float)
	 */
	public static float[] fill(float[] array, float value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(float[], int, int, float)
	 */
	public static float[] fill(float[] array, int fromIndex, int toIndex, float value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(int[], int)
	 */
	public static int[] fill(int[] array, int value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(int[], int, int, int)
	 */
	public static int[] fill(int[] array, int fromIndex, int toIndex, int value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

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

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(Object[], int, int, Object)
	 */
	public static <E> E[] fill(E[] array, int fromIndex, int toIndex, E value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(long[], long)
	 */
	public static long[] fill(long[] array, long value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(long[], int, int, long)
	 */
	public static long[] fill(long[] array, int fromIndex, int toIndex, long value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(short[], short)
	 */
	public static short[] fill(short[] array, short value) {
		Arrays.fill(array, value);
		return array;
	}

	/**
	 * Return the array after it has been "filled".
	 * @see Arrays#fill(short[], int, int, short)
	 */
	public static short[] fill(short[] array, int fromIndex, int toIndex, short value) {
		Arrays.fill(array, fromIndex, toIndex, value);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(byte[])
	 */
	public static byte[] sort(byte... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(byte[], int, int)
	 */
	public static byte[] sort(byte[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(char[])
	 */
	public static char[] sort(char... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(char[], int, int)
	 */
	public static char[] sort(char[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(double[])
	 */
	public static double[] sort(double... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(double[], int, int)
	 */
	public static double[] sort(double[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(float[])
	 */
	public static float[] sort(float... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(float[], int, int)
	 */
	public static float[] sort(float[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(int[])
	 */
	public static int[] sort(int... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(int[], int, int)
	 */
	public static int[] sort(int[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(Object[])
	 */
	public static <E> E[] sort(E... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(Object[], Comparator)
	 */
	public static <E> E[] sort(E[] array, Comparator<? super E> comparator) {
		Arrays.sort(array, comparator);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(Object[], int, int)
	 */
	public static <E> E[] sort(E[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(Object[], int, int, Comparator)
	 */
	public static <E> E[] sort(E[] array, int fromIndex, int toIndex, Comparator<? super E> comparator) {
		Arrays.sort(array, fromIndex, toIndex, comparator);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(long[])
	 */
	public static long[] sort(long... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(long[], int, int)
	 */
	public static long[] sort(long[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(short[])
	 */
	public static short[] sort(short... array) {
		Arrays.sort(array);
		return array;
	}

	/**
	 * Return the array after it has been "sorted".
	 * @see Arrays#sort(short[], int, int)
	 */
	public static short[] sort(short[] array, int fromIndex, int toIndex) {
		Arrays.sort(array, fromIndex, toIndex);
		return array;
	}


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

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

}
