public class LinkedList<E> implements List<E> {
    private ListNode<E> head = null;
    public E get(int i) {
        if (i < 0) {  throw new IllegalArgumentException();  }
        if (head == null) {  throw new IndexOutOfBoundsException();  }
        return head.get(i);
    }
    public void set(int i, E elem) {
        if (i < 0) {  throw new IllegalArgumentException();  }
        if (head == null) {  throw new IndexOutOfBoundsException();  }
        head.set(i, elem);
    }
    public int size() {
        if (head == null) {  return 0;  }
        return head.size();
    }
    public void add(E elem) {
        if (head == null) {
            head = new ListNode<E>(elem, null);
        } else {
            head.add(elem);
        }
    }
    public void add(int i, E elem) {
        if (i < 0) {  throw new IllegalArgumentException();  }
        if (head == null) {
            if (i > 0) {  throw new IndexOutOfBoundsException();  }
            head = new ListNode<E>(elem, null);
        } else {
            head.add(i, elem);
        }
    }
    public void remove(int i) {
       if (i < 0) {
           throw new IllegalArgumentException();
       }
       if (head == null) {
           throw new IndexOutOfBoundsException();
       }
       if (head.getNext() == null) {
            if (i > 0) {  throw new IndexOutOfBoundsException();  }
            head = null;
       } else if (i == 0) {
            head = head.getNext();
       } else {
            head.remove(i);
       }
    }
    public String toString() {
        return "["+(this.head != null ? this.head.toString() : "") + "]";
    }
}
