// Using an array to implement the List interface.
// Barry Cornelius, 19 June 2000
import java.util. Collection;
import java.util. Iterator;
import java.util. List;
import java.util. ListIterator;
public class MyArrayList implements List
{
   // iCapacity indicates the current capacity of the iElements array, and so
   // iElements[0], iElements[1], ..., iElements[iCapacity-1] are available.
   // iSize indicates how many of these elements are being used, and so
   // iElements[0], iElements[1], ..., iElements[iSize-1] are being used.
   private int iCapacity;
   private Object[] iElements;
   private int iSize;
   public MyArrayList()
   {
      this(10);
   }
   public MyArrayList(final int pCapacity)
   {
      iCapacity = pCapacity;
      // the call of clear initializes the fields iElements and iSize
      clear();
   } //BJCHEREFIRST
   private static void iCheckIndex(final int pIndex, final int pMaxIndex)
   {
      if (pIndex<0 || pIndex>pMaxIndex)
      {
         throw new IndexOutOfBoundsException();
      }
      // pIndex>=0 && pIndex<=pMaxIndex
   }
   public void add(final int pIndex, final Object pValue)
   {
      iCheckIndex(pIndex, iSize);
      if (iSize==iCapacity)
      {
         final int tNewCapacity = iCapacity*2;
         final Object[] tNewElements = new Object[tNewCapacity];
         System.arraycopy(iElements, 0, tNewElements, 0,
                          pIndex);
         System.arraycopy(iElements, pIndex, tNewElements, pIndex + 1,
                          iSize - pIndex);
         iCapacity = tNewCapacity;
         iElements = tNewElements;
      }
      else 
      {
         System.arraycopy(iElements, pIndex, iElements, pIndex + 1,
                          iSize - pIndex);
      }
      iElements[pIndex] = pValue;
      iSize++;
   }
   public boolean add(final Object pValue)
   {
      add(iSize, pValue);
      return true;
   }
   public boolean addAll(final int pIndex, final Collection pCollection)
   {
      throw new UnsupportedOperationException();
   }
   public boolean addAll(final Collection pCollection)
   {
      throw new UnsupportedOperationException();
   } //BJCHERECONT
   public void clear()
   {
      iElements = new Object[iCapacity];
      iSize = 0;
   }
   public boolean contains(final Object pValue)
   {
      return indexOf(pValue)>=0;
   }
   public boolean containsAll(final Collection pCollection)
   {
      throw new UnsupportedOperationException();
   }
   public boolean equals(final Object pObject)
   {
      if (pObject==null || getClass()!=pObject.getClass())
      {
         return false;
      }
      final MyArrayList tMyArrayList = (MyArrayList)pObject;
      if (this.iSize!=tMyArrayList.iSize)
      {
         return false;
      }
      for (int tElementNumber = 0; 
               tElementNumber<this.iSize; tElementNumber++)
      {
         final Object tThisObject = this.iElements[tElementNumber];
         final Object tParaObject = tMyArrayList.iElements[tElementNumber];
         if (! tThisObject.equals(tParaObject))
         {
            return false;
         }
      }
      return true;
   }
   public Object get(final int pIndex)
   {
      iCheckIndex(pIndex, iSize - 1);
      return iElements[pIndex];
   }
   public int hashCode()
   {
      return 0;
   } //BJCHERECONT
   public int indexOf(final Object pValue)
   {
      int iPosition = 0;
      while (true)
      {
         if (iPosition==iSize)
         {
            return -1;
         }
         if (iElements[iPosition].equals(pValue))
         {
            return iPosition;
         }
         iPosition++;
      }
   }
   public boolean isEmpty()
   {
      return iSize==0;
   }
   public Iterator iterator()
   {
      return new MyArrayListIterator(iElements, iSize);
   }
   public int lastIndexOf(final Object pValue)
   {
      int iPosition = iSize;
      while (true)
      {
         if (iPosition==0)
         {
            return -1;
         }
         iPosition--;
         if (iElements[iPosition].equals(pValue))
         {
            return iPosition;
         }
      }
   }
   public ListIterator listIterator()
   {
      throw new UnsupportedOperationException();
   } //BJCHERECONT
   public ListIterator listIterator(final int pIndex)
   {
      throw new UnsupportedOperationException();
   }
   public Object remove(final int pIndex)
   {
      iCheckIndex(pIndex, iSize - 1);
      final Object tObject = iElements[pIndex];
      System.arraycopy(iElements, pIndex + 1, iElements, pIndex,
                       iSize - pIndex - 1);
      iSize--;
      return tObject;
   }
   public boolean remove(final Object pValue)
   {
      final int tPosition = indexOf(pValue);
      if (tPosition==-1)
      {
         return false;
      }
      final Object tObject = remove(tPosition);
      return true;
   }
   public boolean removeAll(final Collection pCollection)
   {
      throw new UnsupportedOperationException();
   }
   public boolean retainAll(final Collection pCollection)
   {
      throw new UnsupportedOperationException();
   }
   public Object set(final int pIndex, final Object pValue)
   {
      iCheckIndex(pIndex, iSize - 1);
      final Object tObject = iElements[pIndex];
      iElements[pIndex] = pValue;
      return tObject;
   }
   public int size()
   {
      return iSize;
   }
   public List subList(final int pFromIndex, final int pToIndex)
   {
      throw new UnsupportedOperationException();
   } //BJCHERECONT
   public Object[] toArray()
   {
      throw new UnsupportedOperationException();
   }
   public Object[] toArray(final Object[] pObjects)
   {
      throw new UnsupportedOperationException();
   }
}
