001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections4.list;
018
019import java.io.IOException;
020import java.io.ObjectInputStream;
021import java.io.ObjectOutputStream;
022import java.lang.reflect.Array;
023import java.util.AbstractList;
024import java.util.Collection;
025import java.util.ConcurrentModificationException;
026import java.util.Iterator;
027import java.util.List;
028import java.util.ListIterator;
029import java.util.NoSuchElementException;
030
031import org.apache.commons.collections4.OrderedIterator;
032
033/**
034 * An abstract implementation of a linked list which provides numerous points for
035 * subclasses to override.
036 * <p>
037 * Overridable methods are provided to change the storage node and to change how
038 * nodes are added to and removed. Hopefully, all you need for unusual subclasses
039 * is here.
040 *
041 * @since 3.0
042 */
043public abstract class AbstractLinkedList<E> implements List<E> {
044
045    /*
046     * Implementation notes:
047     * - a standard circular doubly-linked list
048     * - a marker node is stored to mark the start and the end of the list
049     * - node creation and removal always occurs through createNode() and
050     *   removeNode().
051     * - a modification count is kept, with the same semantics as
052     * {@link java.util.LinkedList}.
053     * - respects {@link AbstractList#modCount}
054     */
055
056    /**
057     * A {@link Node} which indicates the start and end of the list and does not
058     * hold a value. The value of <code>next</code> is the first item in the
059     * list. The value of of <code>previous</code> is the last item in the list.
060     */
061    transient Node<E> header;
062
063    /** The size of the list */
064    transient int size;
065
066    /** Modification count for iterators */
067    transient int modCount;
068
069    /**
070     * Constructor that does nothing intended for deserialization.
071     * <p>
072     * If this constructor is used by a serializable subclass then the init()
073     * method must be called.
074     */
075    protected AbstractLinkedList() {
076        super();
077    }
078
079    /**
080     * Constructs a list copying data from the specified collection.
081     *
082     * @param coll  the collection to copy
083     */
084    protected AbstractLinkedList(final Collection<? extends E> coll) {
085        super();
086        init();
087        addAll(coll);
088    }
089
090    /**
091     * The equivalent of a default constructor, broken out so it can be called
092     * by any constructor and by <code>readObject</code>.
093     * Subclasses which override this method should make sure they call super,
094     * so the list is initialised properly.
095     */
096    protected void init() {
097        header = createHeaderNode();
098    }
099
100    //-----------------------------------------------------------------------
101
102    @Override
103    public int size() {
104        return size;
105    }
106
107    @Override
108    public boolean isEmpty() {
109        return size() == 0;
110    }
111
112    @Override
113    public E get(final int index) {
114        final Node<E> node = getNode(index, false);
115        return node.getValue();
116    }
117
118    //-----------------------------------------------------------------------
119
120    @Override
121    public Iterator<E> iterator() {
122        return listIterator();
123    }
124
125    @Override
126    public ListIterator<E> listIterator() {
127        return new LinkedListIterator<>(this, 0);
128    }
129
130    @Override
131    public ListIterator<E> listIterator(final int fromIndex) {
132        return new LinkedListIterator<>(this, fromIndex);
133    }
134
135    //-----------------------------------------------------------------------
136
137    @Override
138    public int indexOf(final Object value) {
139        int i = 0;
140        for (Node<E> node = header.next; node != header; node = node.next) {
141            if (isEqualValue(node.getValue(), value)) {
142                return i;
143            }
144            i++;
145        }
146        return -1;
147    }
148
149    @Override
150    public int lastIndexOf(final Object value) {
151        int i = size - 1;
152        for (Node<E> node = header.previous; node != header; node = node.previous) {
153            if (isEqualValue(node.getValue(), value)) {
154                return i;
155            }
156            i--;
157        }
158        return -1;
159    }
160
161    @Override
162    public boolean contains(final Object value) {
163        return indexOf(value) != -1;
164    }
165
166    @Override
167    public boolean containsAll(final Collection<?> coll) {
168        for (final Object o : coll) {
169            if (!contains(o)) {
170                return false;
171            }
172        }
173        return true;
174    }
175
176    //-----------------------------------------------------------------------
177
178    @Override
179    public Object[] toArray() {
180        return toArray(new Object[size]);
181    }
182
183    @Override
184    @SuppressWarnings("unchecked")
185    public <T> T[] toArray(T[] array) {
186        // Extend the array if needed
187        if (array.length < size) {
188            final Class<?> componentType = array.getClass().getComponentType();
189            array = (T[]) Array.newInstance(componentType, size);
190        }
191        // Copy the values into the array
192        int i = 0;
193        for (Node<E> node = header.next; node != header; node = node.next, i++) {
194            array[i] = (T) node.getValue();
195        }
196        // Set the value after the last value to null
197        if (array.length > size) {
198            array[size] = null;
199        }
200        return array;
201    }
202
203    /**
204     * Gets a sublist of the main list.
205     *
206     * @param fromIndexInclusive  the index to start from
207     * @param toIndexExclusive  the index to end at
208     * @return the new sublist
209     */
210    @Override
211    public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
212        return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive);
213    }
214
215    //-----------------------------------------------------------------------
216
217    @Override
218    public boolean add(final E value) {
219        addLast(value);
220        return true;
221    }
222
223    @Override
224    public void add(final int index, final E value) {
225        final Node<E> node = getNode(index, true);
226        addNodeBefore(node, value);
227    }
228
229    @Override
230    public boolean addAll(final Collection<? extends E> coll) {
231        return addAll(size, coll);
232    }
233
234    @Override
235    public boolean addAll(final int index, final Collection<? extends E> coll) {
236        final Node<E> node = getNode(index, true);
237        for (final E e : coll) {
238            addNodeBefore(node, e);
239        }
240        return true;
241    }
242
243    //-----------------------------------------------------------------------
244
245    @Override
246    public E remove(final int index) {
247        final Node<E> node = getNode(index, false);
248        final E oldValue = node.getValue();
249        removeNode(node);
250        return oldValue;
251    }
252
253    @Override
254    public boolean remove(final Object value) {
255        for (Node<E> node = header.next; node != header; node = node.next) {
256            if (isEqualValue(node.getValue(), value)) {
257                removeNode(node);
258                return true;
259            }
260        }
261        return false;
262    }
263
264    /**
265     * {@inheritDoc}
266     * <p>
267     * This implementation iterates over the elements of this list, checking each element in
268     * turn to see if it's contained in <code>coll</code>. If it's contained, it's removed
269     * from this list. As a consequence, it is advised to use a collection type for
270     * <code>coll</code> that provides a fast (e.g. O(1)) implementation of
271     * {@link Collection#contains(Object)}.
272     */
273    @Override
274    public boolean removeAll(final Collection<?> coll) {
275        boolean modified = false;
276        final Iterator<E> it = iterator();
277        while (it.hasNext()) {
278            if (coll.contains(it.next())) {
279                it.remove();
280                modified = true;
281            }
282        }
283        return modified;
284    }
285
286    //-----------------------------------------------------------------------
287
288    /**
289     * {@inheritDoc}
290     * <p>
291     * This implementation iterates over the elements of this list, checking each element in
292     * turn to see if it's contained in <code>coll</code>. If it's not contained, it's removed
293     * from this list. As a consequence, it is advised to use a collection type for
294     * <code>coll</code> that provides a fast (e.g. O(1)) implementation of
295     * {@link Collection#contains(Object)}.
296     */
297    @Override
298    public boolean retainAll(final Collection<?> coll) {
299        boolean modified = false;
300        final Iterator<E> it = iterator();
301        while (it.hasNext()) {
302            if (coll.contains(it.next()) == false) {
303                it.remove();
304                modified = true;
305            }
306        }
307        return modified;
308    }
309
310    @Override
311    public E set(final int index, final E value) {
312        final Node<E> node = getNode(index, false);
313        final E oldValue = node.getValue();
314        updateNode(node, value);
315        return oldValue;
316    }
317
318    @Override
319    public void clear() {
320        removeAllNodes();
321    }
322
323    //-----------------------------------------------------------------------
324
325    public E getFirst() {
326        final Node<E> node = header.next;
327        if (node == header) {
328            throw new NoSuchElementException();
329        }
330        return node.getValue();
331    }
332
333    public E getLast() {
334        final Node<E> node = header.previous;
335        if (node == header) {
336            throw new NoSuchElementException();
337        }
338        return node.getValue();
339    }
340
341    public boolean addFirst(final E o) {
342        addNodeAfter(header, o);
343        return true;
344    }
345
346    public boolean addLast(final E o) {
347        addNodeBefore(header, o);
348        return true;
349    }
350
351    public E removeFirst() {
352        final Node<E> node = header.next;
353        if (node == header) {
354            throw new NoSuchElementException();
355        }
356        final E oldValue = node.getValue();
357        removeNode(node);
358        return oldValue;
359    }
360
361    public E removeLast() {
362        final Node<E> node = header.previous;
363        if (node == header) {
364            throw new NoSuchElementException();
365        }
366        final E oldValue = node.getValue();
367        removeNode(node);
368        return oldValue;
369    }
370
371    //-----------------------------------------------------------------------
372    @Override
373    public boolean equals(final Object obj) {
374        if (obj == this) {
375            return true;
376        }
377        if (obj instanceof List == false) {
378            return false;
379        }
380        final List<?> other = (List<?>) obj;
381        if (other.size() != size()) {
382            return false;
383        }
384        final ListIterator<?> it1 = listIterator();
385        final ListIterator<?> it2 = other.listIterator();
386        while (it1.hasNext() && it2.hasNext()) {
387            final Object o1 = it1.next();
388            final Object o2 = it2.next();
389            if (!(o1 == null ? o2 == null : o1.equals(o2))) {
390                return false;
391            }
392        }
393        return !(it1.hasNext() || it2.hasNext());
394    }
395
396    @Override
397    public int hashCode() {
398        int hashCode = 1;
399        for (final E e : this) {
400            hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
401        }
402        return hashCode;
403    }
404
405    @Override
406    public String toString() {
407        if (size() == 0) {
408            return "[]";
409        }
410        final StringBuilder buf = new StringBuilder(16 * size());
411        buf.append('[');
412
413        final Iterator<E> it = iterator();
414        boolean hasNext = it.hasNext();
415        while (hasNext) {
416            final Object value = it.next();
417            buf.append(value == this ? "(this Collection)" : value);
418            hasNext = it.hasNext();
419            if (hasNext) {
420                buf.append(", ");
421            }
422        }
423        buf.append(']');
424        return buf.toString();
425    }
426
427    //-----------------------------------------------------------------------
428    /**
429     * Compares two values for equals.
430     * This implementation uses the equals method.
431     * Subclasses can override this to match differently.
432     *
433     * @param value1  the first value to compare, may be null
434     * @param value2  the second value to compare, may be null
435     * @return true if equal
436     */
437    protected boolean isEqualValue(final Object value1, final Object value2) {
438        return value1 == value2 || (value1 == null ? false : value1.equals(value2));
439    }
440
441    /**
442     * Updates the node with a new value.
443     * This implementation sets the value on the node.
444     * Subclasses can override this to record the change.
445     *
446     * @param node  node to update
447     * @param value  new value of the node
448     */
449    protected void updateNode(final Node<E> node, final E value) {
450        node.setValue(value);
451    }
452
453    /**
454     * Creates a new node with previous, next and element all set to null.
455     * This implementation creates a new empty Node.
456     * Subclasses can override this to create a different class.
457     *
458     * @return  newly created node
459     */
460    protected Node<E> createHeaderNode() {
461        return new Node<>();
462    }
463
464    /**
465     * Creates a new node with the specified properties.
466     * This implementation creates a new Node with data.
467     * Subclasses can override this to create a different class.
468     *
469     * @param value  value of the new node
470     * @return a new node containing the value
471     */
472    protected Node<E> createNode(final E value) {
473        return new Node<>(value);
474    }
475
476    /**
477     * Creates a new node with the specified object as its
478     * <code>value</code> and inserts it before <code>node</code>.
479     * <p>
480     * This implementation uses {@link #createNode(Object)} and
481     * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
482     *
483     * @param node  node to insert before
484     * @param value  value of the newly added node
485     * @throws NullPointerException if <code>node</code> is null
486     */
487    protected void addNodeBefore(final Node<E> node, final E value) {
488        final Node<E> newNode = createNode(value);
489        addNode(newNode, node);
490    }
491
492    /**
493     * Creates a new node with the specified object as its
494     * <code>value</code> and inserts it after <code>node</code>.
495     * <p>
496     * This implementation uses {@link #createNode(Object)} and
497     * {@link #addNode(AbstractLinkedList.Node,AbstractLinkedList.Node)}.
498     *
499     * @param node  node to insert after
500     * @param value  value of the newly added node
501     * @throws NullPointerException if <code>node</code> is null
502     */
503    protected void addNodeAfter(final Node<E> node, final E value) {
504        final Node<E> newNode = createNode(value);
505        addNode(newNode, node.next);
506    }
507
508    /**
509     * Inserts a new node into the list.
510     *
511     * @param nodeToInsert  new node to insert
512     * @param insertBeforeNode  node to insert before
513     * @throws NullPointerException if either node is null
514     */
515    protected void addNode(final Node<E> nodeToInsert, final Node<E> insertBeforeNode) {
516        nodeToInsert.next = insertBeforeNode;
517        nodeToInsert.previous = insertBeforeNode.previous;
518        insertBeforeNode.previous.next = nodeToInsert;
519        insertBeforeNode.previous = nodeToInsert;
520        size++;
521        modCount++;
522    }
523
524    /**
525     * Removes the specified node from the list.
526     *
527     * @param node  the node to remove
528     * @throws NullPointerException if <code>node</code> is null
529     */
530    protected void removeNode(final Node<E> node) {
531        node.previous.next = node.next;
532        node.next.previous = node.previous;
533        size--;
534        modCount++;
535    }
536
537    /**
538     * Removes all nodes by resetting the circular list marker.
539     */
540    protected void removeAllNodes() {
541        header.next = header;
542        header.previous = header;
543        size = 0;
544        modCount++;
545    }
546
547    /**
548     * Gets the node at a particular index.
549     *
550     * @param index  the index, starting from 0
551     * @param endMarkerAllowed  whether or not the end marker can be returned if
552     * startIndex is set to the list's size
553     * @return the node at the given index
554     * @throws IndexOutOfBoundsException if the index is less than 0; equal to
555     * the size of the list and endMakerAllowed is false; or greater than the
556     * size of the list
557     */
558    protected Node<E> getNode(final int index, final boolean endMarkerAllowed) throws IndexOutOfBoundsException {
559        // Check the index is within the bounds
560        if (index < 0) {
561            throw new IndexOutOfBoundsException("Couldn't get the node: " +
562                    "index (" + index + ") less than zero.");
563        }
564        if (!endMarkerAllowed && index == size) {
565            throw new IndexOutOfBoundsException("Couldn't get the node: " +
566                    "index (" + index + ") is the size of the list.");
567        }
568        if (index > size) {
569            throw new IndexOutOfBoundsException("Couldn't get the node: " +
570                    "index (" + index + ") greater than the size of the " +
571                    "list (" + size + ").");
572        }
573        // Search the list and get the node
574        Node<E> node;
575        if (index < size / 2) {
576            // Search forwards
577            node = header.next;
578            for (int currentIndex = 0; currentIndex < index; currentIndex++) {
579                node = node.next;
580            }
581        } else {
582            // Search backwards
583            node = header;
584            for (int currentIndex = size; currentIndex > index; currentIndex--) {
585                node = node.previous;
586            }
587        }
588        return node;
589    }
590
591    //-----------------------------------------------------------------------
592    /**
593     * Creates an iterator for the sublist.
594     *
595     * @param subList  the sublist to get an iterator for
596     * @return a new iterator on the given sublist
597     */
598    protected Iterator<E> createSubListIterator(final LinkedSubList<E> subList) {
599        return createSubListListIterator(subList, 0);
600    }
601
602    /**
603     * Creates a list iterator for the sublist.
604     *
605     * @param subList  the sublist to get an iterator for
606     * @param fromIndex  the index to start from, relative to the sublist
607     * @return a new list iterator on the given sublist
608     */
609    protected ListIterator<E> createSubListListIterator(final LinkedSubList<E> subList, final int fromIndex) {
610        return new LinkedSubListIterator<>(subList, fromIndex);
611    }
612
613    //-----------------------------------------------------------------------
614    /**
615     * Serializes the data held in this object to the stream specified.
616     * <p>
617     * The first serializable subclass must call this method from
618     * <code>writeObject</code>.
619     *
620     * @param outputStream  the stream to write the object to
621     * @throws IOException  if anything goes wrong
622     */
623    protected void doWriteObject(final ObjectOutputStream outputStream) throws IOException {
624        // Write the size so we know how many nodes to read back
625        outputStream.writeInt(size());
626        for (final E e : this) {
627            outputStream.writeObject(e);
628        }
629    }
630
631    /**
632     * Deserializes the data held in this object to the stream specified.
633     * <p>
634     * The first serializable subclass must call this method from
635     * <code>readObject</code>.
636     *
637     * @param inputStream  the stream to read the object from
638     * @throws IOException  if any error occurs while reading from the stream
639     * @throws ClassNotFoundException  if a class read from the stream can not be loaded
640     */
641    @SuppressWarnings("unchecked")
642    protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
643        init();
644        final int size = inputStream.readInt();
645        for (int i = 0; i < size; i++) {
646            add((E) inputStream.readObject());
647        }
648    }
649
650    //-----------------------------------------------------------------------
651    /**
652     * A node within the linked list.
653     * <p>
654     * From Commons Collections 3.1, all access to the <code>value</code> property
655     * is via the methods on this class.
656     */
657    protected static class Node<E> {
658
659        /** A pointer to the node before this node */
660        protected Node<E> previous;
661        /** A pointer to the node after this node */
662        protected Node<E> next;
663        /** The object contained within this node */
664        protected E value;
665
666        /**
667         * Constructs a new header node.
668         */
669        protected Node() {
670            super();
671            previous = this;
672            next = this;
673        }
674
675        /**
676         * Constructs a new node.
677         *
678         * @param value  the value to store
679         */
680        protected Node(final E value) {
681            super();
682            this.value = value;
683        }
684
685        /**
686         * Constructs a new node.
687         *
688         * @param previous  the previous node in the list
689         * @param next  the next node in the list
690         * @param value  the value to store
691         */
692        protected Node(final Node<E> previous, final Node<E> next, final E value) {
693            super();
694            this.previous = previous;
695            this.next = next;
696            this.value = value;
697        }
698
699        /**
700         * Gets the value of the node.
701         *
702         * @return the value
703         * @since 3.1
704         */
705        protected E getValue() {
706            return value;
707        }
708
709        /**
710         * Sets the value of the node.
711         *
712         * @param value  the value
713         * @since 3.1
714         */
715        protected void setValue(final E value) {
716            this.value = value;
717        }
718
719        /**
720         * Gets the previous node.
721         *
722         * @return the previous node
723         * @since 3.1
724         */
725        protected Node<E> getPreviousNode() {
726            return previous;
727        }
728
729        /**
730         * Sets the previous node.
731         *
732         * @param previous  the previous node
733         * @since 3.1
734         */
735        protected void setPreviousNode(final Node<E> previous) {
736            this.previous = previous;
737        }
738
739        /**
740         * Gets the next node.
741         *
742         * @return the next node
743         * @since 3.1
744         */
745        protected Node<E> getNextNode() {
746            return next;
747        }
748
749        /**
750         * Sets the next node.
751         *
752         * @param next  the next node
753         * @since 3.1
754         */
755        protected void setNextNode(final Node<E> next) {
756            this.next = next;
757        }
758    }
759
760    //-----------------------------------------------------------------------
761    /**
762     * A list iterator over the linked list.
763     */
764    protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> {
765
766        /** The parent list */
767        protected final AbstractLinkedList<E> parent;
768
769        /**
770         * The node that will be returned by {@link #next()}. If this is equal
771         * to {@link AbstractLinkedList#header} then there are no more values to return.
772         */
773        protected Node<E> next;
774
775        /**
776         * The index of {@link #next}.
777         */
778        protected int nextIndex;
779
780        /**
781         * The last node that was returned by {@link #next()} or {@link
782         * #previous()}. Set to <code>null</code> if {@link #next()} or {@link
783         * #previous()} haven't been called, or if the node has been removed
784         * with {@link #remove()} or a new node added with {@link #add(Object)}.
785         * Should be accessed through {@link #getLastNodeReturned()} to enforce
786         * this behaviour.
787         */
788        protected Node<E> current;
789
790        /**
791         * The modification count that the list is expected to have. If the list
792         * doesn't have this count, then a
793         * {@link java.util.ConcurrentModificationException} may be thrown by
794         * the operations.
795         */
796        protected int expectedModCount;
797
798        /**
799         * Create a ListIterator for a list.
800         *
801         * @param parent  the parent list
802         * @param fromIndex  the index to start at
803         * @throws IndexOutOfBoundsException if fromIndex is less than 0 or greater than the size of the list
804         */
805        protected LinkedListIterator(final AbstractLinkedList<E> parent, final int fromIndex)
806                throws IndexOutOfBoundsException {
807            super();
808            this.parent = parent;
809            this.expectedModCount = parent.modCount;
810            this.next = parent.getNode(fromIndex, true);
811            this.nextIndex = fromIndex;
812        }
813
814        /**
815         * Checks the modification count of the list is the value that this
816         * object expects.
817         *
818         * @throws ConcurrentModificationException If the list's modification
819         * count isn't the value that was expected.
820         */
821        protected void checkModCount() {
822            if (parent.modCount != expectedModCount) {
823                throw new ConcurrentModificationException();
824            }
825        }
826
827        /**
828         * Gets the last node returned.
829         *
830         * @return the last node returned
831         * @throws IllegalStateException If {@link #next()} or {@link #previous()} haven't been called,
832         * or if the node has been removed with {@link #remove()} or a new node added with {@link #add(Object)}.
833         */
834        protected Node<E> getLastNodeReturned() throws IllegalStateException {
835            if (current == null) {
836                throw new IllegalStateException();
837            }
838            return current;
839        }
840
841        @Override
842        public boolean hasNext() {
843            return next != parent.header;
844        }
845
846        @Override
847        public E next() {
848            checkModCount();
849            if (!hasNext()) {
850                throw new NoSuchElementException("No element at index " + nextIndex + ".");
851            }
852            final E value = next.getValue();
853            current = next;
854            next = next.next;
855            nextIndex++;
856            return value;
857        }
858
859        @Override
860        public boolean hasPrevious() {
861            return next.previous != parent.header;
862        }
863
864        @Override
865        public E previous() {
866            checkModCount();
867            if (!hasPrevious()) {
868                throw new NoSuchElementException("Already at start of list.");
869            }
870            next = next.previous;
871            final E value = next.getValue();
872            current = next;
873            nextIndex--;
874            return value;
875        }
876
877        @Override
878        public int nextIndex() {
879            return nextIndex;
880        }
881
882        @Override
883        public int previousIndex() {
884            // not normally overridden, as relative to nextIndex()
885            return nextIndex() - 1;
886        }
887
888        @Override
889        public void remove() {
890            checkModCount();
891            if (current == next) {
892                // remove() following previous()
893                next = next.next;
894                parent.removeNode(getLastNodeReturned());
895            } else {
896                // remove() following next()
897                parent.removeNode(getLastNodeReturned());
898                nextIndex--;
899            }
900            current = null;
901            expectedModCount++;
902        }
903
904        @Override
905        public void set(final E obj) {
906            checkModCount();
907            getLastNodeReturned().setValue(obj);
908        }
909
910        @Override
911        public void add(final E obj) {
912            checkModCount();
913            parent.addNodeBefore(next, obj);
914            current = null;
915            nextIndex++;
916            expectedModCount++;
917        }
918
919    }
920
921    //-----------------------------------------------------------------------
922    /**
923     * A list iterator over the linked sub list.
924     */
925    protected static class LinkedSubListIterator<E> extends LinkedListIterator<E> {
926
927        /** The parent list */
928        protected final LinkedSubList<E> sub;
929
930        protected LinkedSubListIterator(final LinkedSubList<E> sub, final int startIndex) {
931            super(sub.parent, startIndex + sub.offset);
932            this.sub = sub;
933        }
934
935        @Override
936        public boolean hasNext() {
937            return nextIndex() < sub.size;
938        }
939
940        @Override
941        public boolean hasPrevious() {
942            return previousIndex() >= 0;
943        }
944
945        @Override
946        public int nextIndex() {
947            return super.nextIndex() - sub.offset;
948        }
949
950        @Override
951        public void add(final E obj) {
952            super.add(obj);
953            sub.expectedModCount = parent.modCount;
954            sub.size++;
955        }
956
957        @Override
958        public void remove() {
959            super.remove();
960            sub.expectedModCount = parent.modCount;
961            sub.size--;
962        }
963    }
964
965    //-----------------------------------------------------------------------
966    /**
967     * The sublist implementation for AbstractLinkedList.
968     */
969    protected static class LinkedSubList<E> extends AbstractList<E> {
970        /** The main list */
971        AbstractLinkedList<E> parent;
972        /** Offset from the main list */
973        int offset;
974        /** Sublist size */
975        int size;
976        /** Sublist modCount */
977        int expectedModCount;
978
979        protected LinkedSubList(final AbstractLinkedList<E> parent, final int fromIndex, final int toIndex) {
980            if (fromIndex < 0) {
981                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
982            }
983            if (toIndex > parent.size()) {
984                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
985            }
986            if (fromIndex > toIndex) {
987                throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
988            }
989            this.parent = parent;
990            this.offset = fromIndex;
991            this.size = toIndex - fromIndex;
992            this.expectedModCount = parent.modCount;
993        }
994
995        @Override
996        public int size() {
997            checkModCount();
998            return size;
999        }
1000
1001        @Override
1002        public E get(final int index) {
1003            rangeCheck(index, size);
1004            checkModCount();
1005            return parent.get(index + offset);
1006        }
1007
1008        @Override
1009        public void add(final int index, final E obj) {
1010            rangeCheck(index, size + 1);
1011            checkModCount();
1012            parent.add(index + offset, obj);
1013            expectedModCount = parent.modCount;
1014            size++;
1015            LinkedSubList.this.modCount++;
1016        }
1017
1018        @Override
1019        public E remove(final int index) {
1020            rangeCheck(index, size);
1021            checkModCount();
1022            final E result = parent.remove(index + offset);
1023            expectedModCount = parent.modCount;
1024            size--;
1025            LinkedSubList.this.modCount++;
1026            return result;
1027        }
1028
1029        @Override
1030        public boolean addAll(final Collection<? extends E> coll) {
1031            return addAll(size, coll);
1032        }
1033
1034        @Override
1035        public boolean addAll(final int index, final Collection<? extends E> coll) {
1036            rangeCheck(index, size + 1);
1037            final int cSize = coll.size();
1038            if (cSize == 0) {
1039                return false;
1040            }
1041
1042            checkModCount();
1043            parent.addAll(offset + index, coll);
1044            expectedModCount = parent.modCount;
1045            size += cSize;
1046            LinkedSubList.this.modCount++;
1047            return true;
1048        }
1049
1050        @Override
1051        public E set(final int index, final E obj) {
1052            rangeCheck(index, size);
1053            checkModCount();
1054            return parent.set(index + offset, obj);
1055        }
1056
1057        @Override
1058        public void clear() {
1059            checkModCount();
1060            final Iterator<E> it = iterator();
1061            while (it.hasNext()) {
1062                it.next();
1063                it.remove();
1064            }
1065        }
1066
1067        @Override
1068        public Iterator<E> iterator() {
1069            checkModCount();
1070            return parent.createSubListIterator(this);
1071        }
1072
1073        @Override
1074        public ListIterator<E> listIterator(final int index) {
1075            rangeCheck(index, size + 1);
1076            checkModCount();
1077            return parent.createSubListListIterator(this, index);
1078        }
1079
1080        @Override
1081        public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
1082            return new LinkedSubList<>(parent, fromIndexInclusive + offset, toIndexExclusive + offset);
1083        }
1084
1085        protected void rangeCheck(final int index, final int beyond) {
1086            if (index < 0 || index >= beyond) {
1087                throw new IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + size + "'");
1088            }
1089        }
1090
1091        protected void checkModCount() {
1092            if (parent.modCount != expectedModCount) {
1093                throw new ConcurrentModificationException();
1094            }
1095        }
1096    }
1097
1098}