package edu.datastructures.list;

/**
 * @author Artem Pronchakov | email/xmpp: artem.pronchakov@calisto.email
 */
public class LinkedList<T> {

    protected ListElement<T> first;
    protected ListElement<T> last;
    protected int size;

    public void add(T element) {
        if (first == null) {
            first = last = new ListElement<T>(element);
        } else {
            ListElement<T> newLast = new ListElement<T>(element, last);
            last.setNext(newLast);
            newLast.setPrevious(last);
            last = newLast;
        }
        size++;
    }

    public void remove(int index) {
        checkBounds(index);
        

        size--;
    }

    public T getFirst() {
        return first != null ? first.getElement() : null;
    }

    public T getLast() {
        return last != null ? first.getElement() : null;
    }

    public T get(int index) {
        checkBounds(index);
        ListElement<T> curr = first;
        for (int i = 0; i < index; i++) {
            curr = curr.getNext();
        }
        if (curr != null) {
            return curr.getElement();
        } else {
            throw new IndexOutOfBoundsException("There is no such element with index " + index);
        }
    }

    private void checkBounds(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("There is no such element with index " + index);
        }
    }

    protected static class ListElement<E> {
        private E element;
        private ListElement<E> previous;
        private ListElement<E> next;

        public ListElement(E element) {
            this.element = element;
        }

        public ListElement(E element, ListElement<E> previous) {
            this.element = element;
            this.previous = previous;
        }

        public ListElement(E element, ListElement<E> previous, ListElement<E> next) {
            this.element = element;
            this.previous = previous;
            this.next = next;
        }

        public E getElement() {
            return element;
        }

        public void setElement(E element) {
            this.element = element;
        }

        public ListElement<E> getPrevious() {
            return previous;
        }

        public void setPrevious(ListElement<E> previous) {
            this.previous = previous;
        }

        public ListElement<E> getNext() {
            return next;
        }

        public void setNext(ListElement<E> next) {
            this.next = next;
        }

        @Override
        public String toString() {
            return element.toString();
        }
    }

}

@@ -648,16 +648,524 @@
         
+final ListElement%3CT%3E elementToRemove = getListElement(index);%0A%0A        final ListElement%3CT%3E previous = elementToRemove.getPrevious();%0A        final ListElement%3CT%3E next = elementToRemove.getNext();%0A%0A        if (previous != null) %7B%0A            previous.setNext(next);%0A        %7D%0A        if (next != null) %7B%0A            next.setPrevious(previous);%0A        %7D%0A%0A        if (first == elementToRemove) %7B%0A            first = next;%0A        %7D%0A        if (last == elementToRemove) %7B%0A            last = previous;%0A        %7D
 %0A%0A      
@@ -1453,101 +1453,30 @@
 r = 
-first;%0A        for (int i = 0; i %3C index; i++) %7B%0A            curr = curr.getNext();%0A        %7D
+getListElement(index);
 %0A   
@@ -1665,24 +1665,231 @@
    %7D%0A    %7D%0A%0A
+    private ListElement%3CT%3E getListElement(int index) %7B%0A        ListElement%3CT%3E curr = first;%0A        for (int i = 0; i %3C index; i++) %7B%0A            curr = curr.getNext();%0A        %7D%0A        return curr;%0A    %7D%0A%0A
     private 

Remove implemented