/*
 *  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 org.apache.commons.collections;

import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * <p>A customized implementation of <code>java.util.ArrayList</code> designed
 * to operate in a multithreaded environment where the large majority of
 * method calls are read-only, instead of structural changes.  When operating
 * in "fast" mode, read calls are non-synchronized and write calls perform the
 * following steps:</p>
 * <ul>
 * <li>Clone the existing collection
 * <li>Perform the modification on the clone
 * <li>Replace the existing collection with the (modified) clone
 * </ul>
 * <p>When first created, objects of this class default to "slow" mode, where
 * all accesses of any type are synchronized but no cloning takes place.  This
 * is appropriate for initially populating the collection, followed by a switch
 * to "fast" mode (by calling <code>setFast(true)</code>) after initialization
 * is complete.</p>
 *
 * <p><strong>NOTE</strong>: If you are creating and accessing an
 * <code>ArrayList</code> only within a single thread, you should use
 * <code>java.util.ArrayList</code> directly (with no synchronization), for
 * maximum performance.</p>
 *
 * <p><strong>NOTE</strong>: <i>This class is not cross-platform.
 * Using it may cause unexpected failures on some architectures.</i>
 * It suffers from the same problems as the double-checked locking idiom.  
 * In particular, the instruction that clones the internal collection and the 
 * instruction that sets the internal reference to the clone can be executed 
 * or perceived out-of-order.  This means that any read operation might fail 
 * unexpectedly, as it may be reading the state of the internal collection
 * before the internal collection is fully formed.
 * For more information on the double-checked locking idiom, see the
 * <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">
 * Double-Checked Locking Idiom Is Broken Declaration</a>.</p>
 *
 * @since Commons Collections 1.0
 * @version $Revision$ $Date$
 * 
 * @author Craig R. McClanahan
 * @author Stephen Colebourne
 */
public class FastArrayList extends ArrayList {


    // ----------------------------------------------------------- Constructors


    /**
     * Construct a an empty list.
     */
    public FastArrayList() {

        super();
        this.list = new ArrayList();

    }


    /**
     * Construct an empty list with the specified capacity.
     *
     * @param capacity The initial capacity of the empty list
     */
    public FastArrayList(int capacity) {

        super();
        this.list = new ArrayList(capacity);

    }


    /**
     * Construct a list containing the elements of the specified collection,
     * in the order they are returned by the collection's iterator.
     *
     * @param collection The collection whose elements initialize the contents
     *  of this list
     */
    public FastArrayList(Collection collection) {

        super();
        this.list = new ArrayList(collection);

    }


    // ----------------------------------------------------- Instance Variables


    /**
     * The underlying list we are managing.
     */
    protected ArrayList list = null;


    // ------------------------------------------------------------- Properties


    /**
     * Are we operating in "fast" mode?
     */
    protected boolean fast = false;


    /**
     *  Returns true if this list is operating in fast mode.
     *
     *  @return true if this list is operating in fast mode
     */
    public boolean getFast() {
        return (this.fast);
    }

    /**
     *  Sets whether this list will operate in fast mode.
     *
     *  @param fast true if the list should operate in fast mode
     */
    public void setFast(boolean fast) {
        this.fast = fast;
    }


    // --------------------------------------------------------- Public Methods


    /**
     * Appends the specified element to the end of this list.
     *
     * @param element The element to be appended
     */
    public boolean add(Object element) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                boolean result = temp.add(element);
                list = temp;
                return (result);
            }
        } else {
            synchronized (list) {
                return (list.add(element));
            }
        }

    }


    /**
     * Insert the specified element at the specified position in this list,
     * and shift all remaining elements up one position.
     *
     * @param index Index at which to insert this element
     * @param element The element to be inserted
     *
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    public void add(int index, Object element) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                temp.add(index, element);
                list = temp;
            }
        } else {
            synchronized (list) {
                list.add(index, element);
            }
        }

    }


    /**
     * Append all of the elements in the specified Collection to the end
     * of this list, in the order that they are returned by the specified
     * Collection's Iterator.
     *
     * @param collection The collection to be appended
     */
    public boolean addAll(Collection collection) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                boolean result = temp.addAll(collection);
                list = temp;
                return (result);
            }
        } else {
            synchronized (list) {
                return (list.addAll(collection));
            }
        }

    }


    /**
     * Insert all of the elements in the specified Collection at the specified
     * position in this list, and shift any previous elements upwards as
     * needed.
     *
     * @param index Index at which insertion takes place
     * @param collection The collection to be added
     *
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    public boolean addAll(int index, Collection collection) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                boolean result = temp.addAll(index, collection);
                list = temp;
                return (result);
            }
        } else {
            synchronized (list) {
                return (list.addAll(index, collection));
            }
        }

    }


    /**
     * Remove all of the elements from this list.  The list will be empty
     * after this call returns.
     *
     * @throws UnsupportedOperationException if <code>clear()</code>
     *  is not supported by this list
     */
    public void clear() {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                temp.clear();
                list = temp;
            }
        } else {
            synchronized (list) {
                list.clear();
            }
        }

    }


    /**
     * Return a shallow copy of this <code>FastArrayList</code> instance.
     * The elements themselves are not copied.
     */
    public Object clone() {

        FastArrayList results = null;
        if (fast) {
            results = new FastArrayList(list);
        } else {
            synchronized (list) {
                results = new FastArrayList(list);
            }
        }
        results.setFast(getFast());
        return (results);

    }


    /**
     * Return <code>true</code> if this list contains the specified element.
     *
     * @param element The element to test for
     */
    public boolean contains(Object element) {

        if (fast) {
            return (list.contains(element));
        } else {
            synchronized (list) {
                return (list.contains(element));
            }
        }

    }


    /**
     * Return <code>true</code> if this list contains all of the elements
     * in the specified Collection.
     *
     * @param collection Collection whose elements are to be checked
     */
    public boolean containsAll(Collection collection) {

        if (fast) {
            return (list.containsAll(collection));
        } else {
            synchronized (list) {
                return (list.containsAll(collection));
            }
        }

    }


    /**
     * Increase the capacity of this <code>ArrayList</code> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param capacity The new minimum capacity
     */
    public void ensureCapacity(int capacity) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                temp.ensureCapacity(capacity);
                list = temp;
            }
        } else {
            synchronized (list) {
                list.ensureCapacity(capacity);
            }
        }

    }


    /**
     * Compare the specified object with this list for equality.  This
     * implementation uses exactly the code that is used to define the
     * list equals function in the documentation for the
     * <code>List.equals</code> method.
     *
     * @param o Object to be compared to this list
     */
    public boolean equals(Object o) {

        // Simple tests that require no synchronization
        if (o == this)
            return (true);
        else if (!(o instanceof List))
            return (false);
        List lo = (List) o;

        // Compare the sets of elements for equality
        if (fast) {
            ListIterator li1 = list.listIterator();
            ListIterator li2 = lo.listIterator();
            while (li1.hasNext() && li2.hasNext()) {
                Object o1 = li1.next();
                Object o2 = li2.next();
                if (!(o1 == null ? o2 == null : o1.equals(o2)))
                    return (false);
            }
            return (!(li1.hasNext() || li2.hasNext()));
        } else {
            synchronized (list) {
                ListIterator li1 = list.listIterator();
                ListIterator li2 = lo.listIterator();
                while (li1.hasNext() && li2.hasNext()) {
                    Object o1 = li1.next();
                    Object o2 = li2.next();
                    if (!(o1 == null ? o2 == null : o1.equals(o2)))
                        return (false);
                }
                return (!(li1.hasNext() || li2.hasNext()));
            }
        }

    }


    /**
     * Return the element at the specified position in the list.
     *
     * @param index The index of the element to return
     *
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    public Object get(int index) {

        if (fast) {
            return (list.get(index));
        } else {
            synchronized (list) {
                return (list.get(index));
            }
        }

    }


    /**
     * Return the hash code value for this list.  This implementation uses
     * exactly the code that is used to define the list hash function in the
     * documentation for the <code>List.hashCode</code> method.
     */
    public int hashCode() {

        if (fast) {
            int hashCode = 1;
            java.util.Iterator i = list.iterator();
            while (i.hasNext()) {
                Object o = i.next();
                hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
            }
            return (hashCode);
        } else {
            synchronized (list) {
                int hashCode = 1;
                java.util.Iterator i = list.iterator();
                while (i.hasNext()) {
                    Object o = i.next();
                    hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
                }
                return (hashCode);
            }
        }

    }


    /**
     * Search for the first occurrence of the given argument, testing
     * for equality using the <code>equals()</code> method, and return
     * the corresponding index, or -1 if the object is not found.
     *
     * @param element The element to search for
     */
    public int indexOf(Object element) {

        if (fast) {
            return (list.indexOf(element));
        } else {
            synchronized (list) {
                return (list.indexOf(element));
            }
        }

    }


    /**
     * Test if this list has no elements.
     */
    public boolean isEmpty() {

        if (fast) {
            return (list.isEmpty());
        } else {
            synchronized (list) {
                return (list.isEmpty());
            }
        }

    }


    /**
     * Return an iterator over the elements in this list in proper sequence.
     * <p>
     * <b>Thread safety</b><br />
     * The iterator returned is thread-safe ONLY in FAST mode.
     * In slow mode there is no way to synchronize, or make the iterator thread-safe.
     * <p>
     * In fast mode iteration and modification may occur in parallel on different threads,
     * however there is a restriction. Modification must be EITHER via the Iterator
     * interface methods OR the List interface. If a mixture of modification
     * methods is used a ConcurrentModificationException is thrown from the iterator
     * modification method. If the List modification methods are used the changes are
     * NOT visible in the iterator (it shows the list contents at the time the iterator
     * was created).
     * 
     * @return the iterator
     */
    public Iterator iterator() {
        if (fast) {
            return new ListIter(0);
        } else {
            return list.iterator();
        }
    }


    /**
     * Search for the last occurrence of the given argument, testing
     * for equality using the <code>equals()</code> method, and return
     * the corresponding index, or -1 if the object is not found.
     *
     * @param element The element to search for
     */
    public int lastIndexOf(Object element) {

        if (fast) {
            return (list.lastIndexOf(element));
        } else {
            synchronized (list) {
                return (list.lastIndexOf(element));
            }
        }

    }


    /**
     * Return an iterator of the elements of this list, in proper sequence.
     * <p>
     * <b>Thread safety</b><br />
     * The iterator returned is thread-safe ONLY in FAST mode.
     * In slow mode there is no way to synchronize, or make the iterator thread-safe.
     * <p>
     * In fast mode iteration and modification may occur in parallel on different threads,
     * however there is a restriction. Modification must be EITHER via the Iterator
     * interface methods OR the List interface. If a mixture of modification
     * methods is used a ConcurrentModificationException is thrown from the iterator
     * modification method. If the List modification methods are used the changes are
     * NOT visible in the iterator (it shows the list contents at the time the iterator
     * was created).
     * 
     * @return the list iterator
     */
    public ListIterator listIterator() {
        if (fast) {
            return new ListIter(0);
        } else {
            return list.listIterator();
        }
    }


    /**
     * Return an iterator of the elements of this list, in proper sequence,
     * starting at the specified position.
     * <p>
     * <b>Thread safety</b><br />
     * The iterator returned is thread-safe ONLY in FAST mode.
     * In slow mode there is no way to synchronize, or make the iterator thread-safe.
     * <p>
     * In fast mode iteration and modification may occur in parallel on different threads,
     * however there is a restriction. Modification must be EITHER via the Iterator
     * interface methods OR the List interface. If a mixture of modification
     * methods is used a ConcurrentModificationException is thrown from the iterator
     * modification method. If the List modification methods are used the changes are
     * NOT visible in the iterator (it shows the list contents at the time the iterator
     * was created).
     *
     * @param index The starting position of the iterator to return
     * @return the list iterator
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    public ListIterator listIterator(int index) {
        if (fast) {
            return new ListIter(index);
        } else {
            return list.listIterator(index);
        }
    }


    /**
     * Remove the element at the specified position in the list, and shift
     * any subsequent elements down one position.
     *
     * @param index Index of the element to be removed
     *
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    public Object remove(int index) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                Object result = temp.remove(index);
                list = temp;
                return (result);
            }
        } else {
            synchronized (list) {
                return (list.remove(index));
            }
        }

    }


    /**
     * Remove the first occurrence of the specified element from the list,
     * and shift any subsequent elements down one position.
     *
     * @param element Element to be removed
     */
    public boolean remove(Object element) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                boolean result = temp.remove(element);
                list = temp;
                return (result);
            }
        } else {
            synchronized (list) {
                return (list.remove(element));
            }
        }

    }


    /**
     * Remove from this collection all of its elements that are contained
     * in the specified collection.
     *
     * @param collection Collection containing elements to be removed
     *
     * @throws UnsupportedOperationException if this optional operation
     *  is not supported by this list
     */
    public boolean removeAll(Collection collection) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                boolean result = temp.removeAll(collection);
                list = temp;
                return (result);
            }
        } else {
            synchronized (list) {
                return (list.removeAll(collection));
            }
        }

    }


    /**
     * Remove from this collection all of its elements except those that are
     * contained in the specified collection.
     *
     * @param collection Collection containing elements to be retained
     *
     * @throws UnsupportedOperationException if this optional operation
     *  is not supported by this list
     */
    public boolean retainAll(Collection collection) {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                boolean result = temp.retainAll(collection);
                list = temp;
                return (result);
            }
        } else {
            synchronized (list) {
                return (list.retainAll(collection));
            }
        }

    }


    /**
     * Replace the element at the specified position in this list with
     * the specified element.  Returns the previous object at that position.
     * <br><br>
     * <strong>IMPLEMENTATION NOTE</strong> - This operation is specifically
     * documented to not be a structural change, so it is safe to be performed
     * without cloning.
     *
     * @param index Index of the element to replace
     * @param element The new element to be stored
     *
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    public Object set(int index, Object element) {

        if (fast) {
            return (list.set(index, element));
        } else {
            synchronized (list) {
                return (list.set(index, element));
            }
        }

    }


    /**
     * Return the number of elements in this list.
     */
    public int size() {

        if (fast) {
            return (list.size());
        } else {
            synchronized (list) {
                return (list.size());
            }
        }

    }


    /**
     * Return a view of the portion of this list between fromIndex
     * (inclusive) and toIndex (exclusive).  The returned list is backed
     * by this list, so non-structural changes in the returned list are
     * reflected in this list.  The returned list supports
     * all of the optional list operations supported by this list.
     *
     * @param fromIndex The starting index of the sublist view
     * @param toIndex The index after the end of the sublist view
     *
     * @throws IndexOutOfBoundsException if an index is out of range
     */
    public List subList(int fromIndex, int toIndex) {
        if (fast) {
            return new SubList(fromIndex, toIndex);
        } else {
            return list.subList(fromIndex, toIndex);
        }
    }


    /**
     * Return an array containing all of the elements in this list in the
     * correct order.
     */
    public Object[] toArray() {

        if (fast) {
            return (list.toArray());
        } else {
            synchronized (list) {
                return (list.toArray());
            }
        }

    }


    /**
     * Return an array containing all of the elements in this list in the
     * correct order.  The runtime type of the returned array is that of
     * the specified array.  If the list fits in the specified array, it is
     * returned therein.  Otherwise, a new array is allocated with the
     * runtime type of the specified array, and the size of this list.
     *
     * @param array Array defining the element type of the returned list
     *
     * @throws ArrayStoreException if the runtime type of <code>array</code>
     *  is not a supertype of the runtime type of every element in this list
     */
    public Object[] toArray(Object array[]) {

        if (fast) {
            return (list.toArray(array));
        } else {
            synchronized (list) {
                return (list.toArray(array));
            }
        }

    }


    /**
     * Return a String representation of this object.
     */
    public String toString() {

        StringBuffer sb = new StringBuffer("FastArrayList[");
        sb.append(list.toString());
        sb.append("]");
        return (sb.toString());

    }


    /**
     * Trim the capacity of this <code>ArrayList</code> instance to be the
     * list's current size.  An application can use this operation to minimize
     * the storage of an <code>ArrayList</code> instance.
     */
    public void trimToSize() {

        if (fast) {
            synchronized (this) {
                ArrayList temp = (ArrayList) list.clone();
                temp.trimToSize();
                list = temp;
            }
        } else {
            synchronized (list) {
                list.trimToSize();
            }
        }

    }



    private class SubList implements List {

        private int first;
        private int last;
        private List expected;


        public SubList(int first, int last) {
            this.first = first;
            this.last = last;
            this.expected = list;
        }

        private List get(List l) {
            if (list != expected) {
                throw new ConcurrentModificationException();
            }
            return l.subList(first, last);
        }

        public void clear() {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    get(temp).clear();
                    last = first;
                    list = temp;
                    expected = temp;
                }
            } else {
                synchronized (list) {
                    get(expected).clear();
                }
            }
        }

        public boolean remove(Object o) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    boolean r = get(temp).remove(o);
                    if (r) last--;
                    list = temp;
                    expected = temp;
                    return r;
                }
            } else {
                synchronized (list) {
                    return get(expected).remove(o);
                }
            }
        }

        public boolean removeAll(Collection o) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    List sub = get(temp);
                    boolean r = sub.removeAll(o);
                    if (r) last = first + sub.size();
                    list = temp;
                    expected = temp;
                    return r;
                }
            } else {
                synchronized (list) {
                    return get(expected).removeAll(o);
                }
            }
        }

        public boolean retainAll(Collection o) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    List sub = get(temp);
                    boolean r = sub.retainAll(o);
                    if (r) last = first + sub.size();
                    list = temp;
                    expected = temp;
                    return r;
                }
            } else {
                synchronized (list) {
                    return get(expected).retainAll(o);
                }
            }
        }

        public int size() {
            if (fast) {
                return get(expected).size();
            } else {
                synchronized (list) {
                    return get(expected).size();
                }
            }
        }


        public boolean isEmpty() {
            if (fast) {
                return get(expected).isEmpty();
            } else {
                synchronized (list) {
                    return get(expected).isEmpty();
                }
            }
        }

        public boolean contains(Object o) {
            if (fast) {
                return get(expected).contains(o);
            } else {
                synchronized (list) {
                    return get(expected).contains(o);
                }
            }
        }

        public boolean containsAll(Collection o) {
            if (fast) {
                return get(expected).containsAll(o);
            } else {
                synchronized (list) {
                    return get(expected).containsAll(o);
                }
            }
        }

        public Object[] toArray(Object[] o) {
            if (fast) {
                return get(expected).toArray(o);
            } else {
                synchronized (list) {
                    return get(expected).toArray(o);
                }
            }
        }

        public Object[] toArray() {
            if (fast) {
                return get(expected).toArray();
            } else {
                synchronized (list) {
                    return get(expected).toArray();
                }
            }
        }


        public boolean equals(Object o) {
            if (o == this) return true;
            if (fast) {
                return get(expected).equals(o);
            } else {
                synchronized (list) {
                    return get(expected).equals(o);
                }
            }
        }

        public int hashCode() {
            if (fast) {
                return get(expected).hashCode();
            } else {
                synchronized (list) {
                    return get(expected).hashCode();
                }
            }
        }

        public boolean add(Object o) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    boolean r = get(temp).add(o);
                    if (r) last++;
                    list = temp;
                    expected = temp;
                    return r;
                }
            } else {
                synchronized (list) {
                    return get(expected).add(o);
                }
            }
        }

        public boolean addAll(Collection o) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    boolean r = get(temp).addAll(o);
                    if (r) last += o.size();
                    list = temp;
                    expected = temp;
                    return r;
                }
            } else {
                synchronized (list) {
                    return get(expected).addAll(o);
                }
            }
        }

        public void add(int i, Object o) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    get(temp).add(i, o);
                    last++;
                    list = temp;
                    expected = temp;
                }
            } else {
                synchronized (list) {
                    get(expected).add(i, o);
                }
            }
        }

        public boolean addAll(int i, Collection o) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    boolean r = get(temp).addAll(i, o);
                    list = temp;
                    if (r) last += o.size();
                    expected = temp;
                    return r;
                }
            } else {
                synchronized (list) {
                    return get(expected).addAll(i, o);
                }
            }
        }

        public Object remove(int i) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    Object o = get(temp).remove(i);
                    last--;
                    list = temp;
                    expected = temp;
                    return o;
                }
            } else {
                synchronized (list) {
                    return get(expected).remove(i);
                }
            }
        }

        public Object set(int i, Object a) {
            if (fast) {
                synchronized (FastArrayList.this) {
                    ArrayList temp = (ArrayList) list.clone();
                    Object o = get(temp).set(i, a);
                    list = temp;
                    expected = temp;
                    return o;
                }
            } else {
                synchronized (list) {
                    return get(expected).set(i, a);
                }
            }
        }


        public Iterator iterator() {
            return new SubListIter(0);
        }

        public ListIterator listIterator() {
            return new SubListIter(0);
        }

        public ListIterator listIterator(int i) {
            return new SubListIter(i);
        }


        public Object get(int i) {
            if (fast) {
                return get(expected).get(i);
            } else {
                synchronized (list) {
                    return get(expected).get(i);
                }
            }
        }

        public int indexOf(Object o) {
            if (fast) {
                return get(expected).indexOf(o);
            } else {
                synchronized (list) {
                    return get(expected).indexOf(o);
                }
            }
        }


        public int lastIndexOf(Object o) {
            if (fast) {
                return get(expected).lastIndexOf(o);
            } else {
                synchronized (list) {
                    return get(expected).lastIndexOf(o);
                }
            }
        }


        public List subList(int f, int l) {
            if (list != expected) {
                throw new ConcurrentModificationException();
            }
            return new SubList(first + f, f + l);
        }


    private class SubListIter implements ListIterator {

        private List expected;
        private ListIterator iter;
        private int lastReturnedIndex = -1;


        public SubListIter(int i) {
            this.expected = list;
            this.iter = SubList.this.get(expected).listIterator(i);
        }

        private void checkMod() {
            if (list != expected) {
                throw new ConcurrentModificationException();
            }
        }

        List get() {
            return SubList.this.get(expected);
        }

        public boolean hasNext() {
            checkMod();
            return iter.hasNext();     
        }

        public Object next() {
            checkMod();
            lastReturnedIndex = iter.nextIndex();
            return iter.next();
        }

        public boolean hasPrevious() {
            checkMod();
            return iter.hasPrevious();
        }

        public Object previous() {
            checkMod();
            lastReturnedIndex = iter.previousIndex();
            return iter.previous();
        }

        public int previousIndex() {
            checkMod();
            return iter.previousIndex();
        }

        public int nextIndex() {
            checkMod();
            return iter.nextIndex();
        }

        public void remove() {
            checkMod();
            if (lastReturnedIndex < 0) {
                throw new IllegalStateException();
            }
            get().remove(lastReturnedIndex);
            last--;
            expected = list;
            iter = get().listIterator(lastReturnedIndex);
            lastReturnedIndex = -1;
        }

        public void set(Object o) {
            checkMod();
            if (lastReturnedIndex < 0) {
                throw new IllegalStateException();
            }
            get().set(lastReturnedIndex, o);
            expected = list;
            iter = get().listIterator(previousIndex() + 1);
        } 

        public void add(Object o) {
            checkMod();
            int i = nextIndex();
            get().add(i, o);
            last++;
            expected = list;
            iter = get().listIterator(i + 1);
            lastReturnedIndex = -1;
        }

   }


    }



    private class ListIter implements ListIterator {

        private List expected;
        private ListIterator iter;
        private int lastReturnedIndex = -1;


        public ListIter(int i) {
            this.expected = list;
            this.iter = get().listIterator(i);
        }

        private void checkMod() {
            if (list != expected) {
                throw new ConcurrentModificationException();
            }
        }

        List get() {
            return expected;
        }

        public boolean hasNext() {
            return iter.hasNext();     
        }

        public Object next() {
            lastReturnedIndex = iter.nextIndex();
            return iter.next();
        }

        public boolean hasPrevious() {
            return iter.hasPrevious();
        }

        public Object previous() {
            lastReturnedIndex = iter.previousIndex();
            return iter.previous();
        }

        public int previousIndex() {
            return iter.previousIndex();
        }

        public int nextIndex() {
            return iter.nextIndex();
        }

        public void remove() {
            checkMod();
            if (lastReturnedIndex < 0) {
                throw new IllegalStateException();
            }
            get().remove(lastReturnedIndex);
            expected = list;
            iter = get().listIterator(lastReturnedIndex);
            lastReturnedIndex = -1;
        }

        public void set(Object o) {
            checkMod();
            if (lastReturnedIndex < 0) {
                throw new IllegalStateException();
            }
            get().set(lastReturnedIndex, o);
            expected = list;
            iter = get().listIterator(previousIndex() + 1);
        } 

        public void add(Object o) {
            checkMod();
            int i = nextIndex();
            get().add(i, o);
            expected = list;
            iter = get().listIterator(i + 1);
            lastReturnedIndex = -1;
        }

   }
}
