/* pre:  Have object to be added to calling doubly linked list object, and a link in the doubly linked list AFTER
         *       which the newItem's node must be added.
         * post: newItem is the element of the added node of the doubly linked list.  All other existing nodes of the
         *       doubly linked list retain their ordering relevant to the position of the newly added node.
         *       The counter is modified to reflect the addition of a new node to the doubly linked list. */
        public void addAfter(Object newItem, DLLNode link)
        {
            // ADD CODE FOR METHOD addAfter BELOW

            if (link == null)
            {
                this.addLast(newItem);
                return;
            }
            DLLNode newNode = new DLLNode(newItem);
            newNode.setNext(link.next());
            if ((DLLNode)(link.next()) != null)
                ((DLLNode)(link.next())).setPrevious(newNode);
            newNode.setPrevious(link);
            link.setNext(newNode);
            counter++;
        }
        /* pre:  Have object to be added to calling doubly linked list object, and a link in the doubly linked list BEFORE
         *       which the newItem's node must be added.
         * post: newItem is the element of the added node of the doubly linked list.  All other existing nodes of the
         *       doubly linked list retain their ordering relevant to the position of the newly added node.
         *       The counter is modified to reflect the addition of a new node to the doubly linked list. */
        public void addBefore(Object newItem, DLLNode link)
        {
            // ADD CODE FOR METHOD addBefore BELOW

            if (link == null)  // list either empty or must be added at end of list
            {
                this.addLast(newItem);
                return;
            }
            DLLNode newNode = new DLLNode(newItem);
            if (head == link)  // must be added as first node
            {
                this.addFirst(newItem);
                return;
            }
            newNode.setPrevious(link.previous());
            newNode.setNext(link);
            link.previous().setNext(newNode);
            link.setPrevious(newNode);
            counter++;
        }
        /* pre:  Have object to be added to calling doubly linked list object, which may be empty.
        * post: newItem is the element of the LAST node of the doubly linked list.  All other existing nodes of the
        *       doubly linked list retain their ordering BEFORE the new last node.
        *       The counter is modified to reflect the addition of a new node to the doubly linked list. */
        public void addLast(Object newItem)
        {
            // ADD CODE FOR METHOD addLast BELOW

            if (tail == null)
            {
                addFirst(newItem);
                return;
            }
            DLLNode newNode = new DLLNode(newItem);
            newNode.setPrevious(tail);
            tail.setNext(newNode);
            tail = newNode;
            counter++;
        }