/** 
  * An array list iterator that does not support remove (see note below)
  * @author         Edo Biagioni
  * @lecture        ICS 211 Feb 8 (or later)
  * @date           February 6, 2011
  */

private static class ArrayListIterator<E> implements java.util.Iterator<E> {
  private E[] data;
  private int position;        // invariant: position >= 0
  private int limit;           // invariant: limit <= data.length
  private boolean nextCalled;  // keep track of next() being called
  // invariant: if nextCalled is true, position >= 1

  // this constructor takes as parameters the data over which we iterate
  private ArrayListIterator(E[] data, int size) {
    if ((data == null) || (data.length < size)) {
      throw new IllegalArgumentException("illegal call to constructor");
    }
    this.data = data;
    limit = size;    // stop before reaching limit
    position = 0;
    nextCalled = false;
  }

  public boolean hasNext() {
    return (position < limit);
  }

  public E next() {
    if (hasNext()) {
      nextCalled = true;         // allow calling remove()
      E result = data[position];
      position++;
      return result;
    }  // no next element
    throw new java.util.NoSuchElementException("linked list.next");
  }

  /* the only problem with this code for remove is that "limit" is
   * a class variable of this iterator.  Decrementing limit records
   * in the iterator that the collection has gotten smaller, but does
   * not communicate this information to the collection object.
   *
   * fixing this code would require changing the constructor to take
   * as argument an object that holds an int value, and allows us to
   * change it, and to share that value with the Collection class.
   * Since this is just example, code, I have not implemented that.
   */
  public void remove() {
    if (! nextCalled) {
      throw new IllegalStateException ("can only call after next()");
    }
    nextCalled = false;   // no more calls to remove(), until next()
    // invariant: if nextCalled is true, position >= 1
    // item to be removed is at position-1
    for (int i = position; i < limit; i++) {   // O(n) loop
      data [i - 1] = data [i];
    }
    limit--;              // removed one element from the collection
    position--;           // position changes as well
    data[limit] = null;   // optional
  }

}