```
/** Returns whether v is an internal node. */
public boolean isInternal(Position v) throws InvalidPositionException {
return hasLeft(v);  // if v has a right child it will have a left child
}
/** Returns whether v is an external node. */
public boolean isExternal(Position v) throws InvalidPositionException {
return !isInternal(v);
}
/** Returns whether v is the root node. */
public boolean isRoot(Position v) throws InvalidPositionException {
VectorNode vv = checkPosition(v);
return vv.index() == 1;
}
/** Returns whether v has a left child. */
public boolean hasLeft(Position v) throws InvalidPositionException {
VectorNode vv = checkPosition(v);
return 2*vv.index() <= size();
}
/** Returns whether v has a right child. */
public boolean hasRight(Position v) throws InvalidPositionException {
VectorNode vv = checkPosition(v);
return 2*vv.index() + 1 <= size();
}
/** Returns the root of the tree. */
public Position root() throws EmptyTreeException {
if (isEmpty()) throw new EmptyTreeException("Tree is empty");
return (Position)T.elemAtRank(1);
}
/** Returns the left child of v. */
public Position left(Position v)
throws InvalidPositionException, BoundaryViolationException {
if (!hasLeft(v)) throw new BoundaryViolationException("No left child");
return (Position)T.elemAtRank(2*((VectorNode) v).index());
}
/** Returns the right child of v. */
public Position right(Position v)
throws InvalidPositionException {
if (!hasRight(v)) throw new BoundaryViolationException("No right child");
return (Position)T.elemAtRank(2*((VectorNode) v).index() + 1);
}
```