DoublyLinkedList implements Iterable<T> { public ListNode2<T> addAfter(ListNode2<T> node, T value) { ListNode2<T> newNode = new ListNode2<T>(value); addAfter(node, newNode); return newNode; }  ListNode2<T> add(T value); ListNode2<T> enqueue(T value); void add(ListNode2<T> node); ListNode2<T> addAfter(ListNode2<T> node, T value); void addAfter(ListNode2<T> node, ListNode2<T> newNode); void remove(ListNode2<T> node); int size(); @Override Iterator<T> iterator(); T first(); T last(); ListNode2<T> head(); ListNode2<T> tail(); boolean isEmpty(); @SuppressWarnings("unchecked") T[] toArray();  }
@Test public void testAddAfter() { DoublyLinkedList<Integer> list = new DoublyLinkedList<Integer>(); list.add(1); ListNode2<Integer> node2 = list.add(2); ListNode2<Integer> node4 = list.add(4); list.addAfter(node2, 3); assertEquals(4, list.size()); assertArrayEquals(new Integer[]{1, 2, 3, 4}, list.toArray()); ListNode2<Integer> node5 = list.addAfter(node4, 5); assertEquals(5, list.size()); assertArrayEquals(new Integer[]{1, 2, 3, 4, 5}, list.toArray()); assertEquals(new Integer(5), list.last()); assertEquals(node5, list.head()); }