import java.util.Iterator;

/** 
 * A Java interface for the List ADT.
 * 
 * @param <T> The type of items that the list stores.
 * 
 * @author Jadrian Miles
 */
public interface List<T> extends Iterable<T> {
    /** Adds newItem to the end of the list. */
    public void add(T newItem);
    
    /** Adds newItem at the given index.
     * Adds newItem at index newPosition, and shifts each item at or beyond
     * that index to the next higher index.
     *   Note that L.add(L.length(), x) is a valid call, and its effect is
     * equivalent to L.add(x).
     * Postcondition: The item at newPosition is newItem.
     * @throws IndexOutOfBoundsException if newPosition is out of bounds.  For
     *   this method (and only this method), the length of the list is
     *   considered in bounds.
     */
    public void add(int newPosition, T newItem);
    
    /** Removes the item at the given index, and returns it.
     * Removes the item at the given index, shifting each item beyond that index
     * to the next lower index.
     * @throws IndexOutOfBoundsException if position is out of bounds.
     */
    public T remove(int position);
    
    /** Returns the item at a given index.
     * @throws IndexOutOfBoundsException if position is out of bounds.
     */
    public T at(int position);
    
    /** Replaces the item at a given index.
     * @throws IndexOutOfBoundsException if position is out of bounds.
     */
    public void replace(int position, T newItem);
    
    /** Returns true if the list contains the target item.
     * Note that this method is not a canonical List operation; it's included
     * in the interface for Dr. Miles's classes just for the sake of a
     * homework assignment later in the term.
     */
    public boolean contains(T targetItem);
    
    /** Returns the length of the list. */
    public int length();
    
    /** Returns true if the list is empty. */
    public boolean isEmpty();
    
    /** Removes all items from the list. */
    public void clear();
    
    /** Returns an array version of the list.  Note that, for technical reasons,
     * the type of the items contained in the list can't be communicated
     * properly to the caller, so an array of Objects gets returned.
     * @return an array of length length(), with the same items in it as are
     *         stored in the list, in the same order.
     */
    public Object[] toArray();
    
    /** Returns an iterator that begins just before index 0 in this list. */
    public Iterator<T> iterator();
}
