/* Vector.java -- Class that provides growable arrays.
   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util;
import java.lang.reflect.Array;
import java.io.Serializable;

/**
 * The <code>Vector</code> classes implements growable arrays of Objects.
 * You can access elements in a Vector with an index, just as you
 * can in a built in array, but Vectors can grow and shrink to accommodate
 * more or fewer objects.<p>
 *
 * Vectors try to mantain efficiency in growing by having a
 * <code>capacityIncrement</code> that can be specified at instantiation.
 * When a Vector can no longer hold a new Object, it grows by the amount
 * in <code>capacityIncrement</code>. If this value is 0, the vector doubles in
 * size.<p>
 *
 * Vector implements the JDK 1.2 List interface, and is therefore a fully
 * compliant Collection object. The iterators are fail-fast - if external
 * code structurally modifies the vector, any operation on the iterator will
 * then throw a {@link ConcurrentModificationException}. The Vector class is
 * fully synchronized, but the iterators are not. So, when iterating over a
 * vector, be sure to synchronize on the vector itself.  If you don't want the
 * expense of synchronization, use ArrayList instead. On the other hand, the
 * Enumeration of elements() is not thread-safe, nor is it fail-fast; so it
 * can lead to undefined behavior even in a single thread if you modify the
 * vector during iteration.<p>
 *
 * Note: Some methods, especially those specified by List, specify throwing
 * {@link IndexOutOfBoundsException}, but it is easier to implement by
 * throwing the subclass {@link ArrayIndexOutOfBoundsException}. Others
 * directly specify this subclass.
 *
 * @author Scott G. Miller
 * @author Bryce McKinlay
 * @author Eric Blake <ebb9@email.byu.edu>
 * @see Collection
 * @see List
 * @see ArrayList
 * @see LinkedList
 * @since 1.0
 * @status updated to 1.4
 */
public class Vector extends AbstractList
  implements List, RandomAccess, Cloneable, Serializable
{
  /**
   * Compatible with JDK 1.0+.
   */
  private static final long serialVersionUID = -2767605614048989439L;

  /**
   * The internal array used to hold members of a Vector. The elements are
   * in positions 0 through elementCount - 1, and all remaining slots are null.
   * @serial the elements
   */
  protected Object[] elementData;

  /**
   * The number of elements currently in the vector, also returned by
   * {@link #size}.
   * @serial the size
   */
  protected int elementCount;

  /**
   * The amount the Vector's internal array should be increased in size when
   * a new element is added that exceeds the current size of the array,
   * or when {@link #ensureCapacity} is called. If &lt;= 0, the vector just
   * doubles in size.
   * @serial the amount to grow the vector by
   */
  protected int capacityIncrement;

  /**
   * Constructs an empty vector with an initial size of 10, and
   * a capacity increment of 0
   */
  public Vector()
  {
    this(10, 0);
  }

  /**
   * Constructs a vector containing the contents of Collection, in the
   * order given by the collection.
   *
   * @param c collection of elements to add to the new vector
   * @throws NullPointerException if c is null
   * @since 1.2
   */
  public Vector(Collection c)
  {
    elementCount = c.size();
    elementData = c.toArray(new Object[elementCount]);
  }

  /**
   * Constructs a Vector with the initial capacity and capacity
   * increment specified.
   *
   * @param initialCapacity the initial size of the Vector's internal array
   * @param capacityIncrement the amount the internal array should be
   *        increased by when necessary, 0 to double the size
   * @throws IllegalArgumentException if initialCapacity &lt; 0
   */
  public Vector(int initialCapacity, int capacityIncrement)
  {
    if (initialCapacity < 0)
      throw new IllegalArgumentException();
    elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
  }

  /**
   * Constructs a Vector with the initial capacity specified, and a capacity
   * increment of 0 (double in size).
   *
   * @param initialCapacity the initial size of the Vector's internal array
   * @throws IllegalArgumentException if initialCapacity &lt; 0
   */
  public Vector(int initialCapacity)
  {
    this(initialCapacity, 0);
  }

  /**
   * Copies the contents of a provided array into the Vector.  If the
   * array is too large to fit in the Vector, an IndexOutOfBoundsException
   * is thrown without modifying the array.  Old elements in the Vector are
   * overwritten by the new elements.
   *
   * @param a target array for the copy
   * @throws IndexOutOfBoundsException the array is not large enough
   * @throws NullPointerException the array is null
   * @see #toArray(Object[])
   */
  public synchronized void copyInto(Object[] a)
  {
    System.arraycopy(elementData, 0, a, 0, elementCount);
  }

  /**
   * Trims the Vector down to size.  If the internal data array is larger
   * than the number of Objects its holding, a new array is constructed
   * that precisely holds the elements. Otherwise this does nothing.
   */
  public synchronized void trimToSize()
  {
    // Don't bother checking for the case where size() == the capacity of the
    // vector since that is a much less likely case; it's more efficient to
    // not do the check and lose a bit of performance in that infrequent case

    Object[] newArray = new Object[elementCount];
    System.arraycopy(elementData, 0, newArray, 0, elementCount);
    elementData = newArray;
  }

  /**
   * Ensures that <code>minCapacity</code> elements can fit within this Vector.
   * If <code>elementData</code> is too small, it is expanded as follows:
   * If the <code>elementCount + capacityIncrement</code> is adequate, that
   * is the new size. If <code>capacityIncrement</code> is non-zero, the
   * candidate size is double the current. If that is not enough, the new
   * size is <code>minCapacity</code>.
   *
   * @param minCapacity the desired minimum capacity, negative values ignored
   */
  public synchronized void ensureCapacity(int minCapacity)
  {
    if (elementData.length >= minCapacity)
      return;

    int newCapacity;
    if (capacityIncrement <= 0)
      newCapacity = elementData.length * 2;
    else
      newCapacity = elementData.length + capacityIncrement;

    Object[] newArray = new Object[Math.max(newCapacity, minCapacity)];

    System.arraycopy(elementData, 0, newArray, 0, elementCount);
    elementData = newArray;
  }

  /**
   * Explicitly sets the size of the vector (but not necessarily the size of
   * the internal data array). If the new size is smaller than the old one,
   * old values that don't fit are lost. If the new size is larger than the
   * old one, the vector is padded with null entries.
   *
   * @param newSize The new size of the internal array
   * @throws ArrayIndexOutOfBoundsException if the new size is negative
   */
  public synchronized void setSize(int newSize)
  {
    // Don't bother checking for the case where size() == the capacity of the
    // vector since that is a much less likely case; it's more efficient to
    // not do the check and lose a bit of performance in that infrequent case
    modCount++;
    ensureCapacity(newSize);
    if (newSize < elementCount)
      Arrays.fill(elementData, newSize, elementCount, null);
    elementCount = newSize;
  }

  /**
   * Returns the size of the internal data array (not the amount of elements
   * contained in the Vector).
   *
   * @return capacity of the internal data array
   */
  public synchronized int capacity()
  {
    return elementData.length;
  }

  /**
   * Returns the number of elements stored in this Vector.
   *
   * @return the number of elements in this Vector
   */
  public synchronized int size()
  {
    return elementCount;
  }

  /**
   * Returns true if this Vector is empty, false otherwise
   *
   * @return true if the Vector is empty, false otherwise
   */
  public synchronized boolean isEmpty()
  {
    return elementCount == 0;
  }

  /**
   * Returns an Enumeration of the elements of this Vector. The enumeration
   * visits the elements in increasing index order, but is NOT thread-safe.
   *
   * @return an Enumeration
   * @see #iterator()
   */
  // No need to synchronize as the Enumeration is not thread-safe!
  public Enumeration elements()
  {
    return new Enumeration()
    {
      private int i = 0;

      public boolean hasMoreElements()
      {
        return i < elementCount;
      }

      public Object nextElement()
      {
        if (i >= elementCount)
          throw new NoSuchElementException();
        return elementData[i++];
      }
    };
  }

  /**
   * Returns true when <code>elem</code> is contained in this Vector.
   *
   * @param elem the element to check
   * @return true if the object is contained in this Vector, false otherwise
   */
  public boolean contains(Object elem)
  {
    return indexOf(elem, 0) >= 0;
  }

  /**
   * Returns the first occurrence of <code>elem</code> in the Vector, or -1 if
   * <code>elem</code> is not found.
   *
   * @param elem the object to search for
   * @return the index of the first occurrence, or -1 if not found
   */
  public int indexOf(Object elem)
  {
    return indexOf(elem, 0);
  }

  /**
   * Searches the vector starting at <code>index</code> for object
   * <code>elem</code> and returns the index of the first occurrence of this
   * Object.  If the object is not found, or index is larger than the size
   * of the vector, -1 is returned.
   *
   * @param e the Object to search for
   * @param index start searching at this index
   * @return the index of the next occurrence, or -1 if it is not found
   * @throws IndexOutOfBoundsException if index &lt; 0
   */
  public synchronized int indexOf(Object e, int index)
  {
    for (int i = index; i < elementCount; i++)
      if (equals(e, elementData[i]))
        return i;
    return -1;
  }

  /**
   * Returns the last index of <code>elem</code> within this Vector, or -1
   * if the object is not within the Vector.
   *
   * @param elem the object to search for
   * @return the last index of the object, or -1 if not found
   */
  public int lastIndexOf(Object elem)
  {
    return lastIndexOf(elem, elementCount - 1);
  }

  /**
   * Returns the index of the first occurrence of <code>elem</code>, when
   * searching backwards from <code>index</code>.  If the object does not
   * occur in this Vector, or index is less than 0, -1 is returned.
   *
   * @param e the object to search for
   * @param index the index to start searching in reverse from
   * @return the index of the Object if found, -1 otherwise
   * @throws IndexOutOfBoundsException if index &gt;= size()
   */
  public synchronized int lastIndexOf(Object e, int index)
  {
    checkBoundExclusive(index);
    for (int i = index; i >= 0; i--)
      if (equals(e, elementData[i]))
        return i;
    return -1;
  }

  /**
   * Returns the Object stored at <code>index</code>.
   *
   * @param index the index of the Object to retrieve
   * @return the object at <code>index</code>
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @see #get(int)
   */
  public synchronized Object elementAt(int index)
  {
    checkBoundExclusive(index);
    return elementData[index];
  }

  /**
   * Returns the first element (index 0) in the Vector.
   *
   * @return the first Object in the Vector
   * @throws NoSuchElementException the Vector is empty
   */
  public synchronized Object firstElement()
  {
    if (elementCount == 0)
      throw new NoSuchElementException();

    return elementData[0];
  }

  /**
   * Returns the last element in the Vector.
   *
   * @return the last Object in the Vector
   * @throws NoSuchElementException the Vector is empty
   */
  public synchronized Object lastElement()
  {
    if (elementCount == 0)
      throw new NoSuchElementException();

    return elementData[elementCount - 1];
  }

  /**
   * Changes the element at <code>index</code> to be <code>obj</code>
   *
   * @param obj the object to store
   * @param index the position in the Vector to store the object
   * @throws ArrayIndexOutOfBoundsException the index is out of range
   * @see #set(int, Object)
   */
  public void setElementAt(Object obj, int index)
  {
    set(index, obj);
  }

  /**
   * Removes the element at <code>index</code>, and shifts all elements at
   * positions greater than index to their index - 1.
   *
   * @param index the index of the element to remove
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size();
   * @see #remove(int)
   */
  public void removeElementAt(int index)
  {
    remove(index);
  }

  /**
   * Inserts a new element into the Vector at <code>index</code>.  Any elements
   * at or greater than index are shifted up one position.
   *
   * @param obj the object to insert
   * @param index the index at which the object is inserted
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
   * @see #add(int, Object)
   */
  public synchronized void insertElementAt(Object obj, int index)
  {
    checkBoundInclusive(index);
    if (elementCount == elementData.length)
      ensureCapacity(elementCount + 1);
    modCount++;
    System.arraycopy(elementData, index, elementData, index + 1,
                     elementCount - index);
    elementCount++;
    elementData[index] = obj;
  }

  /**
   * Adds an element to the Vector at the end of the Vector.  The vector
   * is increased by ensureCapacity(size() + 1) if needed.
   *
   * @param obj the object to add to the Vector
   */
  public synchronized void addElement(Object obj)
  {
    if (elementCount == elementData.length)
      ensureCapacity(elementCount + 1);
    modCount++;
    elementData[elementCount++] = obj;
  }

  /**
   * Removes the first (the lowestindex) occurance of the given object from
   * the Vector. If such a remove was performed (the object was found), true
   * is returned. If there was no such object, false is returned.
   *
   * @param obj the object to remove from the Vector
   * @return true if the Object was in the Vector, false otherwise
   * @see #remove(Object)
   */
  public synchronized boolean removeElement(Object obj)
  {
    int idx = indexOf(obj, 0);
    if (idx >= 0)
      {
        remove(idx);
        return true;
      }
    return false;
  }

  /**
   * Removes all elements from the Vector.  Note that this does not
   * resize the internal data array.
   *
   * @see #clear()
   */
  public synchronized void removeAllElements()
  {
    if (elementCount == 0)
      return;

    modCount++;
    Arrays.fill(elementData, 0, elementCount, null);
    elementCount = 0;
  }

  /**
   * Creates a new Vector with the same contents as this one. The clone is
   * shallow; elements are not cloned.
   *
   * @return the clone of this vector
   */
  public synchronized Object clone()
  {
    try
      {
        Vector clone = (Vector) super.clone();
        clone.elementData = (Object[]) elementData.clone();
        return clone;
      }
    catch (CloneNotSupportedException ex)
      {
        // Impossible to get here.
        throw new InternalError(ex.toString());
      }
  }

  /**
   * Returns an Object array with the contents of this Vector, in the order
   * they are stored within this Vector.  Note that the Object array returned
   * is not the internal data array, and that it holds only the elements
   * within the Vector.  This is similar to creating a new Object[] with the
   * size of this Vector, then calling Vector.copyInto(yourArray).
   *
   * @return an Object[] containing the contents of this Vector in order
   * @since 1.2
   */
  public synchronized Object[] toArray()
  {
    Object[] newArray = new Object[elementCount];
    copyInto(newArray);
    return newArray;
  }

  /**
   * Returns an array containing the contents of this Vector.
   * If the provided array is large enough, the contents are copied
   * into that array, and a null is placed in the position size().
   * In this manner, you can obtain the size of a Vector by the position
   * of the null element, if you know the vector does not itself contain
   * null entries.  If the array is not large enough, reflection is used
   * to create a bigger one of the same runtime type.
   *
   * @param a an array to copy the Vector into if large enough
   * @return an array with the contents of this Vector in order
   * @throws ArrayStoreException the runtime type of the provided array
   *         cannot hold the elements of the Vector
   * @throws NullPointerException if <code>a</code> is null
   * @since 1.2
   */
  public synchronized Object[] toArray(Object[] a)
  {
    if (a.length < elementCount)
      a = (Object[]) Array.newInstance(a.getClass().getComponentType(),
                                       elementCount);
    else if (a.length > elementCount)
      a[elementCount] = null;
    System.arraycopy(elementData, 0, a, 0, elementCount);
    return a;
  }

  /**
   * Returns the element at position <code>index</code>.
   *
   * @param index the position from which an element will be retrieved
   * @return the element at that position
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @since 1.2
   */
  public Object get(int index)
  {
    return elementAt(index);
  }

  /**
   * Puts <code>element</code> into the Vector at position <code>index</code>
   * and returns the Object that previously occupied that position.
   *
   * @param index the index within the Vector to place the Object
   * @param element the Object to store in the Vector
   * @return the previous object at the specified index
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @since 1.2
   */
  public synchronized Object set(int index, Object element)
  {
    checkBoundExclusive(index);
    Object temp = elementData[index];
    elementData[index] = element;
    return temp;
  }

  /**
   * Adds an object to the Vector.
   *
   * @param o the element to add to the Vector
   * @return true, as specified by List
   * @since 1.2
   */
  public boolean add(Object o)
  {
    addElement(o);
    return true;
  }

  /**
   * Removes the given Object from the Vector.  If it exists, true
   * is returned, if not, false is returned.
   *
   * @param o the object to remove from the Vector
   * @return true if the Object existed in the Vector, false otherwise
   * @since 1.2
   */
  public boolean remove(Object o)
  {
    return removeElement(o);
  }

  /**
   * Adds an object at the specified index.  Elements at or above
   * index are shifted up one position.
   *
   * @param index the index at which to add the element
   * @param element the element to add to the Vector
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
   * @since 1.2
   */
  public void add(int index, Object element)
  {
    insertElementAt(element, index);
  }

  /**
   * Removes the element at the specified index, and returns it.
   *
   * @param index the position from which to remove the element
   * @return the object removed
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @since 1.2
   */
  public synchronized Object remove(int index)
  {
    checkBoundExclusive(index);
    Object temp = elementData[index];
    modCount++;
    elementCount--;
    if (index < elementCount)
      System.arraycopy(elementData, index + 1, elementData, index,
                       elementCount - index);
    elementData[elementCount] = null;
    return temp;
  }

  /**
   * Clears all elements in the Vector and sets its size to 0.
   */
  public void clear()
  {
    removeAllElements();
  }

  /**
   * Returns true if this Vector contains all the elements in c.
   *
   * @param c the collection to compare to
   * @return true if this vector contains all elements of c
   * @throws NullPointerException if c is null
   * @since 1.2
   */
  public synchronized boolean containsAll(Collection c)
  {
    // Here just for the sychronization.
    return super.containsAll(c);
  }

  /**
   * Appends all elements of the given collection to the end of this Vector.
   * Behavior is undefined if the collection is modified during this operation
   * (for example, if this == c).
   *
   * @param c the collection to append
   * @return true if this vector changed, in other words c was not empty
   * @throws NullPointerException if c is null
   * @since 1.2
   */
  public synchronized boolean addAll(Collection c)
  {
    return addAll(elementCount, c);
  }

  /**
   * Remove from this vector all elements contained in the given collection.
   *
   * @param c the collection to filter out
   * @return true if this vector changed
   * @throws NullPointerException if c is null
   * @since 1.2
   */
  public synchronized boolean removeAll(Collection c)
  {
    if (c == null)
      throw new NullPointerException();

    int i;
    int j;
    for (i = 0; i < elementCount; i++)
      if (c.contains(elementData[i]))
        break;
    if (i == elementCount)
      return false;

    modCount++;
    for (j = i++; i < elementCount; i++)
      if (! c.contains(elementData[i]))
        elementData[j++] = elementData[i];
    elementCount -= i - j;
    return true;
  }

  /**
   * Retain in this vector only the elements contained in the given collection.
   *
   * @param c the collection to filter by
   * @return true if this vector changed
   * @throws NullPointerException if c is null
   * @since 1.2
   */
  public synchronized boolean retainAll(Collection c)
  {
    if (c == null)
      throw new NullPointerException();

    int i;
    int j;
    for (i = 0; i < elementCount; i++)
      if (! c.contains(elementData[i]))
        break;
    if (i == elementCount)
      return false;

    modCount++;
    for (j = i++; i < elementCount; i++)
      if (c.contains(elementData[i]))
        elementData[j++] = elementData[i];
    elementCount -= i - j;
    return true;
  }

  /**
   * Inserts all elements of the given collection at the given index of
   * this Vector. Behavior is undefined if the collection is modified during
   * this operation (for example, if this == c).
   *
   * @param c the collection to append
   * @return true if this vector changed, in other words c was not empty
   * @throws NullPointerException if c is null
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
   * @since 1.2
   */
  public synchronized boolean addAll(int index, Collection c)
  {
    checkBoundInclusive(index);
    Iterator itr = c.iterator();
    int csize = c.size();

    modCount++;
    ensureCapacity(elementCount + csize);
    int end = index + csize;
    if (elementCount > 0 && index != elementCount)
      System.arraycopy(elementData, index,
		       elementData, end, elementCount - index);
    elementCount += csize;
    for ( ; index < end; index++)
      elementData[index] = itr.next();
    return (csize > 0);
  }

  /**
   * Compares this to the given object.
   *
   * @param o the object to compare to
   * @return true if the two are equal
   * @since 1.2
   */
  public synchronized boolean equals(Object o)
  {
    // Here just for the sychronization.
    return super.equals(o);
  }

  /**
   * Computes the hashcode of this object.
   *
   * @return the hashcode
   * @since 1.2
   */
  public synchronized int hashCode()
  {
    // Here just for the sychronization.
    return super.hashCode();
  }

  /**
   * Returns a string representation of this Vector in the form
   * "[element0, element1, ... elementN]".
   *
   * @return the String representation of this Vector
   */
  public synchronized String toString()
  {
    // Here just for the sychronization.
    return super.toString();
  }

  /**
   * Obtain a List view of a subsection of this list, from fromIndex
   * (inclusive) to toIndex (exclusive). If the two indices are equal, the
   * sublist is empty. The returned list is modifiable, and changes in one
   * reflect in the other. If this list is structurally modified in
   * any way other than through the returned list, the result of any subsequent
   * operations on the returned list is undefined.
   * <p>
   *
   * @param fromIndex the index that the returned list should start from
   *        (inclusive)
   * @param toIndex the index that the returned list should go to (exclusive)
   * @return a List backed by a subsection of this vector
   * @throws IndexOutOfBoundsException if fromIndex &lt; 0
   *         || toIndex &gt; size()
   * @throws IllegalArgumentException if fromIndex &gt; toIndex
   * @see ConcurrentModificationException
   * @since 1.2
   */
  public synchronized List subList(int fromIndex, int toIndex)
  {
    List sub = super.subList(fromIndex, toIndex);
    // We must specify the correct object to synchronize upon, hence the
    // use of a non-public API
    return new Collections.SynchronizedList(this, sub);
  }

  /**
   * Removes a range of elements from this list.
   * Does nothing when toIndex is equal to fromIndex.
   *
   * @param fromIndex the index to start deleting from (inclusive)
   * @param toIndex the index to delete up to (exclusive)
   * @throws IndexOutOfBoundsException if fromIndex &gt; toIndex
   */
  // This does not need to be synchronized, because it is only called through
  // clear() of a sublist, and clear() had already synchronized.
  protected void removeRange(int fromIndex, int toIndex)
  {
    int change = toIndex - fromIndex;
    if (change > 0)
      {
        modCount++;
        System.arraycopy(elementData, toIndex, elementData, fromIndex,
                         elementCount - toIndex);
        int save = elementCount;
        elementCount -= change;
        Arrays.fill(elementData, elementCount, save, null);
      }
    else if (change < 0)
      throw new IndexOutOfBoundsException();
  }

  /**
   * Checks that the index is in the range of possible elements (inclusive).
   *
   * @param index the index to check
   * @throws ArrayIndexOutOfBoundsException if index &gt; size
   */
  private void checkBoundInclusive(int index)
  {
    // Implementation note: we do not check for negative ranges here, since
    // use of a negative index will cause an ArrayIndexOutOfBoundsException
    // with no effort on our part.
    if (index > elementCount)
      throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount);
  }

  /**
   * Checks that the index is in the range of existing elements (exclusive).
   *
   * @param index the index to check
   * @throws ArrayIndexOutOfBoundsException if index &gt;= size
   */
  private void checkBoundExclusive(int index)
  {
    // Implementation note: we do not check for negative ranges here, since
    // use of a negative index will cause an ArrayIndexOutOfBoundsException
    // with no effort on our part.
    if (index >= elementCount)
      throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
  }
}
