public Position first() // O(1) time throws EmptyContainerException { if (isEmpty()) throw new EmptyContainerException("List is empty"); return header.getNext(); } public Position last() // O(1) time throws EmptyContainerException { if (isEmpty()) throw new EmptyContainerException("List is empty"); return trailer.getPrev(); } public Position before(Position p) // O(1) time throws InvalidPositionException, BoundaryViolationException { DNode v = checkPosition(p); DNode prev = v.getPrev(); if (prev == header) throw new BoundaryViolationException ("Cannot advance past the beginning of the list"); return prev; } public Position insertBefore(Position p, Object element) throws InvalidPositionException { // O(1) time DNode v = checkPosition(p); numElts++; DNode newNode = new DNode(v.getPrev(), v, element); v.getPrev().setNext(newNode); v.setPrev(newNode); return newNode; } public Position insertFirst(Object element) { // O(1) time numElts++; DNode newNode = new DNode(header, header.getNext(), element); header.getNext().setPrev(newNode); header.setNext(newNode); return newNode; }