Help explain the code with line comments public class CompletedList implements ListADT, Iterable { //Three instance variables protected int count; protected int modChange; protected DoubleLinearNode head, tail; //head and tail set to empty count set to zero public CompletedList() { head = tail = null; count = 0; } //Override for head and tail, remove first number of list @Override public T removeFirst() throws NoSuchElementException { //if head is empty return error if(isEmpty()) throw new NoSuchElementException("The collection is empty"); //Temp for each number set to head item T temp = head.getItem(); //if first number equals last they are null if(head == tail) { head = tail = null; } //else the ne else if(head.getNext() == tail) { head.remove(); head = tail; } else { head = head.getNext(); head.getPrev().remove(); } count--; modChange++; return temp; } @Override public T removeLast() throws NoSuchElementException { if(isEmpty()) throw new NoSuchElementException("The collection is empty"); T temp = tail.getItem(); if(head == tail) { head = tail = null; } else if(head.getNext() == tail){ tail.remove(); tail = head; } else { tail = tail.getPrev(); tail.getNext().remove(); } count--; modChange++; return temp; } @Override public T remove( T element ) { if(isEmpty()) throw new NoSuchElementException("The target is not in the collection"); if(tail.getItem().equals(element)) { return removeLast(); } for (DoubleLinearNode current = head; current != null; current = current.getNext()) { if(current.getItem().equals(element)) { if(current == head) { return removeFirst(); } else { count--; modChange++; return current.remove(); } } } throw new NoSuchElementException("The target is not in the collection"); } @Override public T first() { if (isEmpty()) throw new NoSuchElementException("The collection is empty"); return head.getItem(); } @Override public T last() { if (isEmpty()) throw new NoSuchElementException("The collection is empty"); return tail.getItem(); } @Override public boolean contains( T target ) { if(isEmpty()) return false; if(tail.getItem().equals(target)) { return true; } for (DoubleLinearNode current = head; current != null; current = current.getNext()) { if(current.getItem().equals(target)) { return true; } } return false; } @Override public boolean isEmpty() { return count == 0; } @Override public int size() { return count; } @Override public Iterator iterator() { return new ListIterator(head); } @Override public String toString() { StringBuilder sb = new StringBuilder(); for (DoubleLinearNode current = head; current != null; current = current.getNext()) { sb.append(current.getItem()).append(' '); } return sb.toString(); } private class ListIterator implements Iterator { private DoubleLinearNode current; private int modNum; public ListIterator( DoubleLinearNode node) { this.modNum = modChange; this.current = node; } @Override public boolean hasNext() { if(this.modNum != modChange) throw new ConcurrentModificationException("The collection.