/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.util;


/**
 * A {@code List} is a collection which maintains an ordering for its elements. Every
 * element in the {@code List} has an index. Each element can thus be accessed by its
 * index, with the first index being zero. Normally, {@code List}s allow duplicate
 * elements, as compared to Sets, where elements have to be unique.
 * 
 * @since Android 1.0
 */
public interface List<E> extends Collection<E> {
    /**
     * Inserts the specified object into this {@code List} at the specified location.
     * The object is inserted before the current element at the specified
     * location. If the location is equal to the size of this {@code List}, the object
     * is added at the end. If the location is smaller than the size of this
     * {@code List}, then all elements beyond the specified location are moved by one
     * position towards the end of the {@code List}.
     * 
     * @param location
     *            the index at which to insert.
     * @param object
     *            the object to add.
     * @exception UnsupportedOperationException
     *                when adding to this {@code List} is not supported.
     * @exception ClassCastException
     *                when the class of the object is inappropriate for this
     *                {@code List}.
     * @exception IllegalArgumentException
     *                when the object cannot be added to this {@code List}.
     * @exception IndexOutOfBoundsException
     *                when {@code location < 0 || location > size()}
     * @since Android 1.0
     */
    public void add(int location, E object);

    /**
     * Adds the specified object at the end of this {@code List}.
     * 
     * @param object
     *            the object to add.
     * @return always true.
     * @exception UnsupportedOperationException
     *                when adding to this {@code List} is not supported.
     * @exception ClassCastException
     *                when the class of the object is inappropriate for this
     *                {@code List}.
     * @exception IllegalArgumentException
     *                when the object cannot be added to this {@code List}.
     * @since Android 1.0
     */
    public boolean add(E object);

    /**
     * Inserts the objects in the specified collection at the specified location
     * in this {@code List}. The objects are added in the order they are returned from
     * the collection's iterator.
     * 
     * @param location
     *            the index at which to insert.
     * @param collection
     *            the collection of objects to be inserted.
     * @return true if this {@code List} has been modified through the insertion, false
     *         otherwise (i.e. if the passed collection was empty).
     * @exception UnsupportedOperationException
     *                when adding to this {@code List} is not supported.
     * @exception ClassCastException
     *                when the class of an object is inappropriate for this
     *                {@code List}.
     * @exception IllegalArgumentException
     *                when an object cannot be added to this {@code List}.
     * @exception IndexOutOfBoundsException
     *                when {@code location < 0 || > size()}
     * @since Android 1.0
     */
    public boolean addAll(int location, Collection<? extends E> collection);

    /**
     * Adds the objects in the specified collection to the end of this {@code List}. The
     * objects are added in the order in which they are returned from the
     * collection's iterator.
     * 
     * @param collection
     *            the collection of objects.
     * @return {@code true} if this {@code List} is modified, {@code false} otherwise
     *         (i.e. if the passed collection was empty).
     * @exception UnsupportedOperationException
     *                when adding to this {@code List} is not supported.
     * @exception ClassCastException
     *                when the class of an object is inappropriate for this
     *                {@code List}.
     * @exception IllegalArgumentException
     *                when an object cannot be added to this {@code List}.
     * @since Android 1.0
     */
    public boolean addAll(Collection<? extends E> collection);

    /**
     * Removes all elements from this {@code List}, leaving it empty.
     * 
     * @exception UnsupportedOperationException
     *                when removing from this {@code List} is not supported.
     * @see #isEmpty
     * @see #size
     * @since Android 1.0
     */
    public void clear();

    /**
     * Tests whether this {@code List} contains the specified object.
     * 
     * @param object
     *            the object to search for.
     * @return {@code true} if object is an element of this {@code List}, {@code false}
     *         otherwise
     * @since Android 1.0
     */
    public boolean contains(Object object);

    /**
     * Tests whether this {@code List} contains all objects contained in the
     * specified collection.
     * 
     * @param collection
     *            the collection of objects
     * @return {@code true} if all objects in the specified collection are
     *         elements of this {@code List}, {@code false} otherwise.
     * @since Android 1.0
     */
    public boolean containsAll(Collection<?> collection);

    /**
     * Compares the given object with the {@code List}, and returns true if they
     * represent the <em>same</em> object using a class specific comparison. For
     * {@code List}s, this means that they contain the same elements in exactly the same
     * order.
     * 
     * @param object
     *            the object to compare with this object.
     * @return boolean {@code true} if the object is the same as this object,
     *         and {@code false} if it is different from this object.
     * @see #hashCode
     * @since Android 1.0
     */
    public boolean equals(Object object);

    /**
     * Returns the element at the specified location in this {@code List}.
     * 
     * @param location
     *            the index of the element to return.
     * @return the element at the specified location.
     * @exception IndexOutOfBoundsException
     *                when {@code location < 0 || >= size()}
     * @since Android 1.0
     */
    public E get(int location);

    /**
     * Returns the hash code for this {@code List}. It is calculated by taking each
     * element' hashcode and its position in the {@code List} into account.
     * 
     * @return the hash code of the {@code List}.
     * @since Android 1.0
     */
    public int hashCode();

    /**
     * Searches this {@code List} for the specified object and returns the index of the
     * first occurrence.
     * 
     * @param object
     *            the object to search for.
     * @return the index of the first occurrence of the object or -1 if the
     *         object was not found.
     * @since Android 1.0
     */
    public int indexOf(Object object);

    /**
     * Returns whether this {@code List} contains no elements.
     * 
     * @return {@code true} if this {@code List} has no elements, {@code false}
     *         otherwise.
     * @see #size
     * @since Android 1.0
     */
    public boolean isEmpty();

    /**
     * Returns an iterator on the elements of this {@code List}. The elements are
     * iterated in the same order as they occur in the {@code List}.
     * 
     * @return an iterator on the elements of this {@code List}.
     * @see Iterator
     * @since Android 1.0
     */
    public Iterator<E> iterator();

    /**
     * Searches this {@code List} for the specified object and returns the index of the
     * last occurrence.
     * 
     * @param object
     *            the object to search for.
     * @return the index of the last occurrence of the object, or -1 if the
     *         object was not found.
     * @since Android 1.0
     */
    public int lastIndexOf(Object object);

    /**
     * Returns a {@code List} iterator on the elements of this {@code List}. The elements are
     * iterated in the same order that they occur in the {@code List}.
     * 
     * @return a {@code List} iterator on the elements of this {@code List}
     * 
     * @see ListIterator
     * @since Android 1.0
     */
    public ListIterator<E> listIterator();

    /**
     * Returns a list iterator on the elements of this {@code List}. The elements are
     * iterated in the same order as they occur in the {@code List}. The iteration
     * starts at the specified location.
     * 
     * @param location
     *            the index at which to start the iteration.
     * @return a list iterator on the elements of this {@code List}.
     * @exception IndexOutOfBoundsException
     *                when {@code location < 0 || location > size()}
     * @see ListIterator
     * @since Android 1.0
     */
    public ListIterator<E> listIterator(int location);

    /**
     * Removes the object at the specified location from this {@code List}.
     * 
     * @param location
     *            the index of the object to remove.
     * @return the removed object.
     * @exception UnsupportedOperationException
     *                when removing from this {@code List} is not supported.
     * @exception IndexOutOfBoundsException
     *                when {@code location < 0 || >= size()}
     * @since Android 1.0
     */
    public E remove(int location);

    /**
     * Removes the first occurrence of the specified object from this {@code List}.
     * 
     * @param object
     *            the object to remove.
     * @return true if this {@code List} was modified by this operation, false
     *         otherwise.
     * @exception UnsupportedOperationException
     *                when removing from this {@code List} is not supported.
     * @since Android 1.0
     */
    public boolean remove(Object object);

    /**
     * Removes all occurrences in this {@code List} of each object in the specified
     * collection.
     * 
     * @param collection
     *            the collection of objects to remove.
     * @return {@code true} if this {@code List} is modified, {@code false} otherwise.
     * @exception UnsupportedOperationException
     *                when removing from this {@code List} is not supported.
     * @since Android 1.0
     */
    public boolean removeAll(Collection<?> collection);

    /**
     * Removes all objects from this {@code List} that are not contained in the
     * specified collection.
     * 
     * @param collection
     *            the collection of objects to retain.
     * @return {@code true} if this {@code List} is modified, {@code false} otherwise.
     * @exception UnsupportedOperationException
     *                when removing from this {@code List} is not supported.
     * @since Android 1.0
     */
    public boolean retainAll(Collection<?> collection);

    /**
     * Replaces the element at the specified location in this {@code List} with the
     * specified object. This operation does not change the size of the {@code List}.
     * 
     * @param location
     *            the index at which to put the specified object.
     * @param object
     *            the object to insert.
     * @return the previous element at the index.
     * @exception UnsupportedOperationException
     *                when replacing elements in this {@code List} is not supported.
     * @exception ClassCastException
     *                when the class of an object is inappropriate for this
     *                {@code List}.
     * @exception IllegalArgumentException
     *                when an object cannot be added to this {@code List}.
     * @exception IndexOutOfBoundsException
     *                when {@code location < 0 || >= size()}
     * @since Android 1.0
     */
    public E set(int location, E object);

    /**
     * Returns the number of elements in this {@code List}.
     * 
     * @return the number of elements in this {@code List}.
     * @since Android 1.0
     */
    public int size();

    /**
     * Returns a {@code List} of the specified portion of this {@code List} from the given start
     * index to the end index minus one. The returned {@code List} is backed by this
     * {@code List} so changes to it are reflected by the other.
     * 
     * @param start
     *            the index at which to start the sublist.
     * @param end
     *            the index one past the end of the sublist.
     * @return a list of a portion of this {@code List}.
     * @exception IndexOutOfBoundsException
     *                when {@code start < 0, start > end} or {@code end >
     *                size()}
     * @since Android 1.0
     */
    public List<E> subList(int start, int end);

    /**
     * Returns an array containing all elements contained in this {@code List}.
     * 
     * @return an array of the elements from this {@code List}.
     * @since Android 1.0
     */
    public Object[] toArray();

    /**
     * Returns an array containing all elements contained in this {@code List}. If the
     * specified array is large enough to hold the elements, the specified array
     * is used, otherwise an array of the same type is created. If the specified
     * array is used and is larger than this {@code List}, the array element following
     * the collection elements is set to null.
     * 
     * @param array
     *            the array.
     * @return an array of the elements from this {@code List}.
     * @exception ArrayStoreException
     *                when the type of an element in this {@code List} cannot be stored
     *                in the type of the specified array.
     * @since Android 1.0
     */
    public <T> T[] toArray(T[] array);
}
