/**
   * Position at index i in range[1,numElements-1]. Next must be value "i" and previous must be
   * value "i-1"
   */
  public void testMiddleIndexSetting() {

    for (int i = 1; i <= numElements - 1; i++) {

      iter = list.listIterator(i);
      Object next = iter.next();

      iter = list.listIterator(i);
      Object prev = iter.previous();

      assertTrue(next.equals(i));
      assertTrue(prev.equals(i - 1));
    }
  }
  /*
   * Do the Samba! Perform a random sequence of next and previous
   * and check if you are at the correct point in the list
   */
  public void testSamba() {

    Random random = new Random();
    final int sambaSteps = 1;

    iter = list.listIterator(numElements / 2); // Position roughly in the middle
    int pos = numElements / 2;

    for (int i = 0; i < sambaSteps; i++) {
      boolean next = random.nextBoolean();

      // Randomly jump ahead or back
      // pos keeps track of where you should be
      if (next && iter.hasNext()) {
        iter.next();
        pos = pos + 1;
      } else if (!next && iter.hasPrevious()) {
        iter.previous();
        pos = pos - 1;
      }
    }

    // Check to see if you are where you ought to be
    assertTrue((pos == numElements) || (iter.next().equals(pos)));
  }
  public void testRemoveLast() {
    iter = list.listIterator(numElements);
    Object last = iter.previous();
    iter.remove();

    assertEquals(list.size(), numElements - 1);
    assertTrue(last.equals(numElements - 1));
  }
  public void testRemoveFirst() {
    iter = list.listIterator();
    Object first = iter.next();
    iter.remove();

    assertEquals(list.size(), numElements - 1);
    assertTrue(first.equals(0));
  }
  public void testReverse() {
    // Reverse the list.

    if (list.size() > 1) {
      ListIterator back = list.listIterator(numElements);
      ListIterator front = list.listIterator();

      for (int i = 0; i < list.size() / 2; i++) {
        Object frontOjb = front.next(), backObj = back.previous();
        front.set(backObj);
        back.set(frontOjb);
      }

      assertEquals(list.size(), numElements);
      for (int i = 0; i < numElements; i++) assertTrue(list.get(i).equals(numElements - 1 - i));
    }
  }
  /**
   * You need to have called next (or previous) to call remove Try to do remove without calling next
   * and see that an exception is thrown
   */
  public void testTryRemoveWithoutNext() {

    boolean threwException = false;

    iter = list.listIterator();
    try {
      iter.remove(); // Try removing without having called next
    } catch (IllegalStateException e) {
      threwException = true; // Control should get to this point
    }

    assertTrue(threwException);
  }
  /** Check if previous is working correctly. */
  public void testPrevious() {

    iter = list.listIterator(numElements);

    Object prev;
    for (int i = 0; i < numElements - 1; i++) {
      prev = iter.previous();
      assertTrue(prev.equals(numElements - i - 1));
      assertTrue(iter.hasPrevious());
    }

    prev = iter.previous();
    assertTrue(prev.equals(0));

    assertFalse(iter.hasPrevious());
  }
  public void testSet() {

    // Double the values in the list using set

    iter = list.listIterator();

    while (iter.hasNext()) {
      int next = (Integer) iter.next();
      next *= 2;
      iter.set(next);
    }

    // Check if the doubling got done right

    assertEquals(list.size(), numElements);
    for (int i = 0; i < numElements; i++) assertTrue(list.get(i).equals(2 * i));
  }
  /** Check if next works correctly */
  public void testNext() {

    // Move down one at a time
    // Check if this is being done correctly

    iter = list.listIterator();
    Object next;

    for (int i = 0; i < numElements - 1; i++) {
      next = iter.next();
      assertTrue(next.equals(i));
      assertTrue(iter.hasNext());
    }

    next = iter.next();
    assertTrue(next.equals(numElements - 1));
    assertFalse(iter.hasNext());
  }