// ... (continuation of NodeList) Position first() const // return first element throw(EmptyContainerException) { if (isEmpty()) throw EmptyContainerException("List is empty"); return Position(header->next); } Position before(const Position& p) const // return item before p throw(BoundaryViolationException, InvalidPositionException) { NodePtr v = nodePtr(p); NodePtr prev = v->prev; if (prev == header) throw BoundaryViolationException("Advance past beginning of list"); return Position(prev); } Position insertAfter(const Position& p, const Object& element) throw(InvalidPositionException) { // insert after p NodePtr v = nodePtr(p); sz++; NodePtr newNode = new Node(element, v, v->next); v->next->prev = newNode; // link node into list v->next = newNode; return Position(newNode); } void remove(const Position& p) // remove a given node throw(InvalidPositionException) { sz--; NodePtr v = nodePtr(p); v->prev->next = v->next; // unlink from the list v->next->prev = v->prev; delete v; } void replaceElement(const Position& p, const Object& element) throw(InvalidPositionException) { // replace element NodePtr v = nodePtr(p); v->element = element; } // ... (some functions omitted) };