/** Returns the parent of v. */
  public Position parent(Position v) 
    throws InvalidPositionException, BoundaryViolationException { 
    if (isRoot(v)) throw new BoundaryViolationException("No parent");
    return (Position)T.elemAtRank(((VectorNode) v).index() / 2);
  }
  /** Replaces the element at v. */
  public Object replace(Position v, Object o) throws InvalidPositionException {
    VectorNode vv = checkPosition(v);
    return vv.setElement(o);
  }
  /** Add an element just after the last node (in a level numbering). */
  public Position add(Object e) {
    int rankToInsert = size()+1;
    Position p = new VectorNode(e,rankToInsert);
    T.insertAtRank(rankToInsert,p);
    return p;
  }
  /** Removes and returns the element at the last node. */
  public Object remove() throws EmptyTreeException {
    if(isEmpty()) throw new EmptyTreeException("Tree is empty");
    return ((Position)T.removeAtRank(size())).element(); 
  }
  /** Determine whether v is a valid node. */
  protected VectorNode checkPosition(Position v) 
    throws InvalidPositionException 
  {
    if (v == null || !(v instanceof VectorNode))
      throw new InvalidPositionException("Position is invalid");
    return (VectorNode)v;
  }
  /** Returns an iterator of the elements stored at all nodes in the tree. */
  public Iterator elements() { 
    List list = new NodeList();
    for(int i = 0; i < size(); i++)
      list.insertLast(((Position)T.elemAtRank(i+1)).element());
    return list.elements();
  } 
} // methods children and positions are omitted here (same as LinkedBinaryTree)