/** Inserts the given node z before the given node v. An error
    * occurs if v is the header */
  public void addBefore(DNode v, DNode z) throws IllegalArgumentException {
    DNode u = getPrev(v);	// may throw an IllegalArgumentException
    z.setPrev(u);
    z.setNext(v);
    v.setPrev(z);
    u.setNext(z);
    size++;
  }
  /** Inserts the given node z after the given node v. An error occurs
    * if v is the trailer */
  public void addAfter(DNode v, DNode z) {
    DNode w = getNext(v);	// may throw an IllegalArgumentException
    z.setPrev(v);
    z.setNext(w);
    w.setPrev(z);
    v.setNext(z);
    size++;
  }
  /** Inserts the given node at the head of the list */
  public void addFirst(DNode v) {
    addAfter(header, v);
  }
  /** Inserts the given node at the tail of the list */
  public void addLast(DNode v) {
    addBefore(trailer, v);
  }
  /** Removes the given node v from the list. An error occurs if v is
    * the header or trailer */
  public void remove(DNode v) {
    DNode u = getPrev(v);	// may throw an IllegalArgumentException
    DNode w = getNext(v);	// may throw an IllegalArgumentException
    // unlink the node from the list 
    w.setPrev(u);
    u.setNext(w);
    v.setPrev(null);
    v.setNext(null);
    size--;
  }