View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.list;
18  
19  import static org.junit.jupiter.api.Assertions.assertAll;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertNotSame;
23  import static org.junit.jupiter.api.Assertions.assertNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.util.ArrayList;
29  import java.util.ConcurrentModificationException;
30  import java.util.HashSet;
31  import java.util.Iterator;
32  import java.util.LinkedList;
33  import java.util.List;
34  import java.util.ListIterator;
35  import java.util.NoSuchElementException;
36  
37  import org.apache.commons.lang3.ArrayUtils;
38  import org.junit.jupiter.api.BeforeEach;
39  import org.junit.jupiter.api.Test;
40  
41  /**
42   * Test class.
43   */
44  public class CursorableLinkedListTest<E> extends AbstractLinkedListTest<E> {
45  
46      private CursorableLinkedList<E> list;
47      public CursorableLinkedListTest() {
48          super(CursorableLinkedListTest.class.getSimpleName());
49      }
50  
51      @Override
52      public String getCompatibilityVersion() {
53          return "4";
54      }
55  
56      /**
57       *  Ignore the serialization tests for sublists and sub-sublists.
58       *
59       *  @return an array of sublist serialization test names
60       */
61      @Override
62      public String[] ignoredTests() {
63          final ArrayList<String> list = new ArrayList<>();
64          final String prefix = "CursorableLinkedListTest";
65          final String bulk = ".bulkTestSubList";
66          final String[] ignored = {
67              ".testEmptyListSerialization",
68              ".testFullListSerialization",
69              ".testEmptyListCompatibility",
70              ".testFullListCompatibility",
71              ".testSimpleSerialization",
72              ".testCanonicalEmptyCollectionExists",
73              ".testCanonicalFullCollectionExists",
74              ".testSerializeDeserializeThenCompare"
75          };
76          for (final String element : ignored) {
77              list.add(prefix + bulk + element);
78              list.add(prefix + bulk + bulk + element);
79          }
80          return list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
81      }
82  
83      @Override
84      public CursorableLinkedList<E> makeObject() {
85          return new CursorableLinkedList<>();
86      }
87  
88      @BeforeEach
89      public void setUp() {
90          list = new CursorableLinkedList<>();
91      }
92  
93      @Test
94      @SuppressWarnings("unchecked")
95      public void testAdd() {
96          assertEquals("[]", list.toString());
97          assertTrue(list.add((E) Integer.valueOf(1)));
98          assertEquals("[1]", list.toString());
99          assertTrue(list.add((E) Integer.valueOf(2)));
100         assertEquals("[1, 2]", list.toString());
101         assertTrue(list.add((E) Integer.valueOf(3)));
102         assertEquals("[1, 2, 3]", list.toString());
103         assertTrue(list.addFirst((E) Integer.valueOf(0)));
104         assertEquals("[0, 1, 2, 3]", list.toString());
105         assertTrue(list.addLast((E) Integer.valueOf(4)));
106         assertEquals("[0, 1, 2, 3, 4]", list.toString());
107         list.add(0, (E) Integer.valueOf(-2));
108         assertEquals("[-2, 0, 1, 2, 3, 4]", list.toString());
109         list.add(1, (E) Integer.valueOf(-1));
110         assertEquals("[-2, -1, 0, 1, 2, 3, 4]", list.toString());
111         list.add(7, (E) Integer.valueOf(5));
112         assertEquals("[-2, -1, 0, 1, 2, 3, 4, 5]", list.toString());
113 
114         final List<E> list2 = new LinkedList<>();
115         list2.add((E) "A");
116         list2.add((E) "B");
117         list2.add((E) "C");
118 
119         assertTrue(list.addAll(list2));
120         assertEquals("[-2, -1, 0, 1, 2, 3, 4, 5, A, B, C]", list.toString());
121         assertTrue(list.addAll(3, list2));
122         assertEquals("[-2, -1, 0, A, B, C, 1, 2, 3, 4, 5, A, B, C]", list.toString());
123     }
124 
125     @Test
126     @SuppressWarnings("unchecked")
127     public void testClear() {
128         assertEquals(0, list.size());
129         assertTrue(list.isEmpty());
130         list.clear();
131         assertEquals(0, list.size());
132         assertTrue(list.isEmpty());
133 
134         list.add((E) "element");
135         assertEquals(1, list.size());
136         assertFalse(list.isEmpty());
137 
138         list.clear();
139         assertEquals(0, list.size());
140         assertTrue(list.isEmpty());
141 
142         list.add((E) "element1");
143         list.add((E) "element2");
144         assertEquals(2, list.size());
145         assertFalse(list.isEmpty());
146 
147         list.clear();
148         assertEquals(0, list.size());
149         assertTrue(list.isEmpty());
150 
151         for (int i = 0; i < 1000; i++) {
152             list.add((E) Integer.valueOf(i));
153         }
154         assertEquals(1000, list.size());
155         assertFalse(list.isEmpty());
156 
157         list.clear();
158         assertEquals(0, list.size());
159         assertTrue(list.isEmpty());
160     }
161 
162     @Test
163     @SuppressWarnings("unchecked")
164     public void testContains() {
165         assertFalse(list.contains("A"));
166         assertTrue(list.add((E) "A"));
167         assertTrue(list.contains("A"));
168         assertTrue(list.add((E) "B"));
169         assertTrue(list.contains("A"));
170         assertTrue(list.addFirst((E) "a"));
171         assertTrue(list.contains("A"));
172         assertTrue(list.remove("a"));
173         assertTrue(list.contains("A"));
174         assertTrue(list.remove("A"));
175         assertFalse(list.contains("A"));
176     }
177 
178     @Test
179     @SuppressWarnings("unchecked")
180     public void testContainsAll() {
181         assertTrue(list.containsAll(list));
182         final java.util.List<E> list2 = new java.util.LinkedList<>();
183         assertTrue(list.containsAll(list2));
184         list2.add((E) "A");
185         assertFalse(list.containsAll(list2));
186         list.add((E) "B");
187         list.add((E) "A");
188         assertTrue(list.containsAll(list2));
189         list2.add((E) "B");
190         assertTrue(list.containsAll(list2));
191         list2.add((E) "C");
192         assertFalse(list.containsAll(list2));
193         list.add((E) "C");
194         assertTrue(list.containsAll(list2));
195         list2.add((E) "C");
196         assertTrue(list.containsAll(list2));
197         assertTrue(list.containsAll(list));
198     }
199 
200     @Test
201     @SuppressWarnings("unchecked")
202     public void testCursorAdd() {
203         final CursorableLinkedList.Cursor<E> it = list.cursor();
204         it.add((E) "1");
205         assertEquals("[1]", list.toString());
206         it.add((E) "3");
207         assertEquals("[1, 3]", list.toString());
208         it.add((E) "5");
209         assertEquals("[1, 3, 5]", list.toString());
210         assertEquals("5", it.previous());
211         it.add((E) "4");
212         assertEquals("[1, 3, 4, 5]", list.toString());
213         assertEquals("4", it.previous());
214         assertEquals("3", it.previous());
215         it.add((E) "2");
216         assertEquals("[1, 2, 3, 4, 5]", list.toString());
217         it.close();
218     }
219 
220     @Test
221     @SuppressWarnings("unchecked")
222     public void testCursorConcurrentModification() {
223         // this test verifies that cursors remain valid when the list
224         // is modified via other means.
225         list.add((E) "1");
226         list.add((E) "2");
227         list.add((E) "3");
228         list.add((E) "5");
229         list.add((E) "7");
230         list.add((E) "9");
231 
232         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
233         final CursorableLinkedList.Cursor<E> c2 = list.cursor();
234         final Iterator<E> li = list.iterator();
235 
236         // test cursors remain valid when list modified by std Iterator
237         // test cursors skip elements removed via ListIterator
238         assertEquals("1", li.next());
239         assertEquals("2", li.next());
240         li.remove();
241         assertEquals("3", li.next());
242         assertEquals("1", c1.next());
243         assertEquals("3", c1.next());
244         assertEquals("1", c2.next());
245 
246         // test cursor c1 can remove elements from previously modified list
247         // test cursor c2 skips elements removed via different cursor
248         c1.remove();
249         assertEquals("5", c2.next());
250         c2.add((E) "6");
251         assertEquals("5", c1.next());
252         assertEquals("6", c1.next());
253         assertEquals("7", c1.next());
254 
255         // test cursors remain valid when list mod via CursorableLinkedList
256         // test cursor remains valid when elements inserted into list before
257         // the current position of the cursor.
258         list.add(0, (E) "0");
259 
260         // test cursor remains valid when element inserted immediately after
261         // current element of a cursor, and the element is seen on the
262         // next call to the next method of that cursor.
263         list.add(5, (E) "8");
264 
265         assertEquals("8", c1.next());
266         assertEquals("9", c1.next());
267         c1.add((E) "10");
268         assertEquals("7", c2.next());
269         assertEquals("8", c2.next());
270         assertEquals("9", c2.next());
271         assertEquals("10", c2.next());
272 
273         assertThrows(NoSuchElementException.class, () -> c2.next());
274 
275         assertThrows(ConcurrentModificationException.class, () -> li.next());
276 
277         c1.close(); // not necessary
278         c2.close(); // not necessary
279     }
280 
281     @Test
282     @SuppressWarnings("unchecked")
283     public void testCursorNavigation() {
284         list.add((E) "1");
285         list.add((E) "2");
286         list.add((E) "3");
287         list.add((E) "4");
288         list.add((E) "5");
289         final CursorableLinkedList.Cursor<E> it = list.cursor();
290         assertTrue(it.hasNext());
291         assertFalse(it.hasPrevious());
292         assertEquals("1", it.next());
293         assertTrue(it.hasNext());
294         assertTrue(it.hasPrevious());
295         assertEquals("1", it.previous());
296         assertTrue(it.hasNext());
297         assertFalse(it.hasPrevious());
298         assertEquals("1", it.next());
299         assertTrue(it.hasNext());
300         assertTrue(it.hasPrevious());
301         assertEquals("2", it.next());
302         assertTrue(it.hasNext());
303         assertTrue(it.hasPrevious());
304         assertEquals("2", it.previous());
305         assertTrue(it.hasNext());
306         assertTrue(it.hasPrevious());
307         assertEquals("2", it.next());
308         assertTrue(it.hasNext());
309         assertTrue(it.hasPrevious());
310         assertEquals("3", it.next());
311         assertTrue(it.hasNext());
312         assertTrue(it.hasPrevious());
313         assertEquals("4", it.next());
314         assertTrue(it.hasNext());
315         assertTrue(it.hasPrevious());
316         assertEquals("5", it.next());
317         assertFalse(it.hasNext());
318         assertTrue(it.hasPrevious());
319         assertEquals("5", it.previous());
320         assertTrue(it.hasNext());
321         assertTrue(it.hasPrevious());
322         assertEquals("4", it.previous());
323         assertTrue(it.hasNext());
324         assertTrue(it.hasPrevious());
325         assertEquals("3", it.previous());
326         assertTrue(it.hasNext());
327         assertTrue(it.hasPrevious());
328         assertEquals("2", it.previous());
329         assertTrue(it.hasNext());
330         assertTrue(it.hasPrevious());
331         assertEquals("1", it.previous());
332         assertTrue(it.hasNext());
333         assertFalse(it.hasPrevious());
334         it.close();
335     }
336 
337     @Test
338     @SuppressWarnings("unchecked")
339     public void testCursorNextIndexAddAfter() {
340         list.add((E) "1");
341         list.add((E) "2");
342         list.add((E) "3");
343         list.add((E) "5");
344 
345         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
346 
347         assertEquals(0, c1.nextIndex());
348         list.add(1, (E) "0");
349         assertEquals(0, c1.nextIndex());
350         assertEquals("1", c1.next());
351         assertEquals(1, c1.nextIndex());
352         assertEquals("0", c1.next());
353     }
354 
355     @Test
356     @SuppressWarnings("unchecked")
357     public void testCursorNextIndexAddBefore() {
358         list.add((E) "1");
359         list.add((E) "2");
360         list.add((E) "3");
361         list.add((E) "5");
362 
363         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
364 
365         assertEquals(0, c1.nextIndex());
366         assertEquals("1", c1.next());
367         list.add(0, (E) "0");
368         assertEquals(2, c1.nextIndex());
369         assertEquals("2", c1.next());
370     }
371 
372     @Test
373     @SuppressWarnings("unchecked")
374     public void testCursorNextIndexAddNext() {
375         list.add((E) "1");
376         list.add((E) "2");
377         list.add((E) "3");
378         list.add((E) "5");
379 
380         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
381 
382         assertEquals(0, c1.nextIndex());
383         list.add(0, (E) "0");
384         assertEquals(0, c1.nextIndex());
385         assertEquals("0", c1.next());
386         assertEquals(1, c1.nextIndex());
387         assertEquals("1", c1.next());
388     }
389 
390     @Test
391     @SuppressWarnings("unchecked")
392     public void testCursorNextIndexFirst() {
393         list.add((E) "1");
394         list.add((E) "2");
395         list.add((E) "3");
396         list.add((E) "5");
397 
398         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
399 
400         assertEquals(0, c1.nextIndex());
401         list.remove(0);
402         assertEquals(0, c1.nextIndex());
403         assertEquals("2", c1.next());
404         assertEquals(1, c1.nextIndex());
405         assertEquals("3", c1.next());
406     }
407 
408     @Test
409     @SuppressWarnings("unchecked")
410     public void testCursorNextIndexMid() {
411         list.add((E) "1");
412         list.add((E) "2");
413         list.add((E) "3");
414         list.add((E) "5");
415 
416         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
417         final Iterator<E> li = list.iterator();
418 
419         // test cursors remain valid when list modified by std Iterator
420         // test cursors skip elements removed via ListIterator
421         assertEquals("1", li.next());
422         assertEquals("2", li.next());
423         li.remove();
424         assertEquals(0, c1.nextIndex());
425         assertEquals("1", c1.next());
426         assertEquals(1, c1.nextIndex());
427         assertEquals("3", c1.next());
428     }
429 
430     @Test
431     @SuppressWarnings("unchecked")
432     public void testCursorRemove() {
433         list.add((E) "1");
434         list.add((E) "2");
435         list.add((E) "3");
436         list.add((E) "4");
437         list.add((E) "5");
438 
439         final CursorableLinkedList.Cursor<E> it = list.cursor();
440 
441         assertThrows(IllegalStateException.class, () -> it.remove());
442 
443         assertEquals("1", it.next());
444         assertEquals("2", it.next());
445         assertEquals("[1, 2, 3, 4, 5]", list.toString());
446         it.remove();
447         assertEquals("[1, 3, 4, 5]", list.toString());
448         assertEquals("3", it.next());
449         assertEquals("3", it.previous());
450         assertEquals("1", it.previous());
451         it.remove();
452         assertEquals("[3, 4, 5]", list.toString());
453         assertFalse(it.hasPrevious());
454         assertEquals("3", it.next());
455         it.remove();
456         assertEquals("[4, 5]", list.toString());
457         try {
458             it.remove();
459         } catch (final IllegalStateException e) {
460             // expected
461         }
462         assertEquals("4", it.next());
463         assertEquals("5", it.next());
464         it.remove();
465         assertEquals("[4]", list.toString());
466         assertEquals("4", it.previous());
467         it.remove();
468         assertEquals("[]", list.toString());
469         it.close();
470     }
471 
472     @Test
473     @SuppressWarnings("unchecked")
474     public void testCursorSet() {
475         list.add((E) "1");
476         list.add((E) "2");
477         list.add((E) "3");
478         list.add((E) "4");
479         list.add((E) "5");
480 
481         final CursorableLinkedList.Cursor<E> it = list.cursor();
482         assertEquals("1", it.next());
483         it.set((E) "a");
484         assertEquals("a", it.previous());
485         it.set((E) "A");
486         assertEquals("A", it.next());
487         assertEquals("2", it.next());
488         it.set((E) "B");
489         assertEquals("3", it.next());
490         assertEquals("4", it.next());
491         it.set((E) "D");
492         assertEquals("5", it.next());
493         it.set((E) "E");
494         assertEquals("[A, B, 3, D, E]", list.toString());
495         it.close();
496     }
497 
498     @Test
499     @SuppressWarnings("unchecked")
500     public void testEqualsAndHashCode() {
501         assertEquals(list, list);
502         assertEquals(list.hashCode(), list.hashCode());
503         list.add((E) "A");
504         assertEquals(list, list);
505         assertEquals(list.hashCode(), list.hashCode());
506 
507         final CursorableLinkedList<E> list2 = new CursorableLinkedList<>();
508         assertFalse(list.equals(list2));
509         assertFalse(list2.equals(list));
510 
511         final java.util.List<E> list3 = new java.util.LinkedList<>();
512         assertFalse(list.equals(list3));
513         assertFalse(list3.equals(list));
514         assertEquals(list2, list3);
515         assertEquals(list3, list2);
516         assertEquals(list2.hashCode(), list3.hashCode());
517 
518         list2.add((E) "A");
519         assertEquals(list, list2);
520         assertEquals(list2, list);
521         assertFalse(list2.equals(list3));
522         assertFalse(list3.equals(list2));
523 
524         list3.add((E) "A");
525         assertEquals(list2, list3);
526         assertEquals(list3, list2);
527         assertEquals(list2.hashCode(), list3.hashCode());
528 
529         list.add((E) "B");
530         assertEquals(list, list);
531         assertFalse(list.equals(list2));
532         assertFalse(list2.equals(list));
533         assertFalse(list.equals(list3));
534         assertFalse(list3.equals(list));
535 
536         list2.add((E) "B");
537         list3.add((E) "B");
538         assertEquals(list, list);
539         assertEquals(list, list2);
540         assertEquals(list2, list);
541         assertEquals(list2, list3);
542         assertEquals(list3, list2);
543         assertEquals(list2.hashCode(), list3.hashCode());
544 
545         list.add((E) "C");
546         list2.add((E) "C");
547         list3.add((E) "C");
548         assertEquals(list, list);
549         assertEquals(list, list2);
550         assertEquals(list2, list);
551         assertEquals(list2, list3);
552         assertEquals(list3, list2);
553         assertEquals(list.hashCode(), list2.hashCode());
554         assertEquals(list2.hashCode(), list3.hashCode());
555 
556         list.add((E) "D");
557         list2.addFirst((E) "D");
558         assertEquals(list, list);
559         assertFalse(list.equals(list2));
560         assertFalse(list2.equals(list));
561     }
562 
563     @Test
564     @SuppressWarnings("unchecked")
565     public void testGet() {
566         assertThrows(IndexOutOfBoundsException.class, () -> list.get(0),
567                 "shouldn't get here");
568 
569         assertTrue(list.add((E) "A"));
570         assertEquals("A", list.get(0));
571         assertTrue(list.add((E) "B"));
572         assertEquals("A", list.get(0));
573         assertEquals("B", list.get(1));
574         assertAll(
575                 () -> assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1),
576                         "shouldn't get here"),
577                 () -> assertThrows(IndexOutOfBoundsException.class, () -> list.get(2),
578                         "shouldn't get here")
579         );
580     }
581 
582     @Test
583     @SuppressWarnings("unchecked")
584     public void testIndexOf() {
585         assertEquals(-1, list.indexOf("A"));
586         assertEquals(-1, list.lastIndexOf("A"));
587         list.add((E) "A");
588         assertEquals(0, list.indexOf("A"));
589         assertEquals(0, list.lastIndexOf("A"));
590         assertEquals(-1, list.indexOf("B"));
591         assertEquals(-1, list.lastIndexOf("B"));
592         list.add((E) "B");
593         assertEquals(0, list.indexOf("A"));
594         assertEquals(0, list.lastIndexOf("A"));
595         assertEquals(1, list.indexOf("B"));
596         assertEquals(1, list.lastIndexOf("B"));
597         list.addFirst((E) "B");
598         assertEquals(1, list.indexOf("A"));
599         assertEquals(1, list.lastIndexOf("A"));
600         assertEquals(0, list.indexOf("B"));
601         assertEquals(2, list.lastIndexOf("B"));
602     }
603 
604     @Test
605     @SuppressWarnings("unchecked")
606     public void testInternalState_CursorNextAddIndex1ByList() {
607         list.add((E) "A");
608         list.add((E) "B");
609         list.add((E) "C");
610 
611         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
612         assertEquals("A", c1.next());
613 
614         list.add(1, (E) "Z");
615 
616         assertTrue(c1.nextIndexValid);
617         assertEquals(1, c1.nextIndex);
618         assertEquals("A", c1.current.value);
619         assertEquals("Z", c1.next.value);
620 
621         assertEquals("[A, Z, B, C]", list.toString());
622         c1.remove();  // works ok
623         assertEquals("[Z, B, C]", list.toString());
624 
625         assertThrows(IllegalStateException.class, () -> c1.remove());
626     }
627 
628     @Test
629     @SuppressWarnings("unchecked")
630     public void testInternalState_CursorNextNextAddByIterator() {
631         list.add((E) "A");
632         list.add((E) "B");
633         list.add((E) "C");
634 
635         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
636         assertEquals("A", c1.next());
637         assertEquals("B", c1.next());
638 
639         c1.add((E) "Z");
640 
641         assertTrue(c1.nextIndexValid);
642         assertEquals(3, c1.nextIndex);
643         assertFalse(c1.currentRemovedByAnother);
644         assertNull(c1.current);
645         assertEquals("C", c1.next.value);
646 
647         assertEquals("[A, B, Z, C]", list.toString());
648 
649         assertThrows(IllegalStateException.class, () -> c1.remove());
650     }
651 
652     @Test
653     @SuppressWarnings("unchecked")
654     public void testInternalState_CursorNextNextAddIndex1ByList() {
655         list.add((E) "A");
656         list.add((E) "B");
657         list.add((E) "C");
658 
659         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
660         assertEquals("A", c1.next());
661         assertEquals("B", c1.next());
662 
663         list.add(1, (E) "Z");
664 
665         assertFalse(c1.nextIndexValid);
666         assertEquals("B", c1.current.value);
667         assertEquals("C", c1.next.value);
668 
669         assertEquals("[A, Z, B, C]", list.toString());
670         c1.remove();  // works ok
671         assertEquals("[A, Z, C]", list.toString());
672 
673         assertThrows(IllegalStateException.class, () -> c1.remove());
674     }
675 
676     @Test
677     @SuppressWarnings("unchecked")
678     public void testInternalState_CursorNextNextNextRemoveIndex1ByList() {
679         list.add((E) "A");
680         list.add((E) "B");
681         list.add((E) "C");
682         list.add((E) "D");
683 
684         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
685         assertEquals("A", c1.next());
686         assertEquals("B", c1.next());
687         assertEquals("C", c1.next());
688 
689         assertEquals("B", list.remove(1));
690 
691         assertFalse(c1.nextIndexValid);
692         assertFalse(c1.currentRemovedByAnother);
693         assertEquals("C", c1.current.value);
694         assertEquals("D", c1.next.value);
695 
696         assertEquals("[A, C, D]", list.toString());
697         c1.remove();  // works ok
698         assertEquals("[A, D]", list.toString());
699 
700         assertThrows(IllegalStateException.class, () -> c1.remove());
701     }
702 
703     @Test
704     @SuppressWarnings("unchecked")
705     public void testInternalState_CursorNextNextPreviousAddByIterator() {
706         list.add((E) "A");
707         list.add((E) "B");
708         list.add((E) "C");
709 
710         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
711         assertEquals("A", c1.next());
712         assertEquals("B", c1.next());
713         assertEquals("B", c1.previous());
714 
715         c1.add((E) "Z");
716 
717         assertTrue(c1.nextIndexValid);
718         assertEquals(2, c1.nextIndex);
719         assertNull(c1.current);
720         assertEquals("B", c1.next.value);
721 
722         assertEquals("[A, Z, B, C]", list.toString());
723 
724         assertThrows(IllegalStateException.class, () -> c1.remove());
725     }
726 
727     @Test
728     @SuppressWarnings("unchecked")
729     public void testInternalState_CursorNextNextPreviousAddIndex1ByList() {
730         list.add((E) "A");
731         list.add((E) "B");
732         list.add((E) "C");
733 
734         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
735         assertEquals("A", c1.next());
736         assertEquals("B", c1.next());
737         assertEquals("B", c1.previous());
738 
739         list.add(1, (E) "Z");
740 
741         assertTrue(c1.nextIndexValid);
742         assertEquals(1, c1.nextIndex);
743         assertEquals("B", c1.current.value);
744         assertEquals("Z", c1.next.value);
745 
746         assertEquals("[A, Z, B, C]", list.toString());
747         c1.remove();  // works ok
748         assertEquals("[A, Z, C]", list.toString());
749 
750         assertThrows(IllegalStateException.class, () -> c1.remove());
751     }
752 
753     @Test
754     @SuppressWarnings("unchecked")
755     public void testInternalState_CursorNextNextPreviousRemoveByIterator() {
756         list.add((E) "A");
757         list.add((E) "B");
758         list.add((E) "C");
759 
760         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
761         assertEquals("A", c1.next());
762         assertEquals("B", c1.next());
763         assertEquals("B", c1.previous());
764 
765         c1.remove();
766 
767         assertTrue(c1.nextIndexValid);
768         assertEquals(1, c1.nextIndex);
769         assertFalse(c1.currentRemovedByAnother);
770         assertNull(c1.current);
771         assertEquals("C", c1.next.value);
772 
773         assertEquals("[A, C]", list.toString());
774 
775         assertThrows(IllegalStateException.class, () -> c1.remove());
776     }
777 
778     @Test
779     @SuppressWarnings("unchecked")
780     public void testInternalState_CursorNextNextPreviousRemoveIndex1ByList() {
781         list.add((E) "A");
782         list.add((E) "B");
783         list.add((E) "C");
784 
785         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
786         assertEquals("A", c1.next());
787         assertEquals("B", c1.next());
788         assertEquals("B", c1.previous());
789 
790         assertEquals("B", list.remove(1));
791 
792         assertTrue(c1.nextIndexValid);
793         assertEquals(1, c1.nextIndex);
794         assertTrue(c1.currentRemovedByAnother);
795         assertNull(c1.current);
796         assertEquals("C", c1.next.value);
797 
798         assertEquals("[A, C]", list.toString());
799         c1.remove();  // works ok
800         assertEquals("[A, C]", list.toString());
801 
802         assertThrows(IllegalStateException.class, () -> c1.remove());
803     }
804 
805     @Test
806     @SuppressWarnings("unchecked")
807     public void testInternalState_CursorNextNextPreviousSetByIterator() {
808         list.add((E) "A");
809         list.add((E) "B");
810         list.add((E) "C");
811 
812         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
813         assertEquals("A", c1.next());
814         assertEquals("B", c1.next());
815         assertEquals("B", c1.previous());
816 
817         c1.set((E) "Z");
818 
819         assertTrue(c1.nextIndexValid);
820         assertEquals(1, c1.nextIndex);
821         assertEquals("Z", c1.current.value);
822         assertEquals("Z", c1.next.value);
823 
824         assertEquals("[A, Z, C]", list.toString());
825         c1.remove();  // works ok
826         assertEquals("[A, C]", list.toString());
827 
828         assertThrows(IllegalStateException.class, () -> c1.remove());
829     }
830 
831     @Test
832     @SuppressWarnings("unchecked")
833     public void testInternalState_CursorNextNextRemoveByIterator() {
834         list.add((E) "A");
835         list.add((E) "B");
836         list.add((E) "C");
837 
838         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
839         assertEquals("A", c1.next());
840         assertEquals("B", c1.next());
841 
842         c1.remove();
843 
844         assertTrue(c1.nextIndexValid);
845         assertEquals(1, c1.nextIndex);
846         assertFalse(c1.currentRemovedByAnother);
847         assertNull(c1.current);
848         assertEquals("C", c1.next.value);
849 
850         assertEquals("[A, C]", list.toString());
851 
852         assertThrows(IllegalStateException.class, () -> c1.remove());
853     }
854 
855     @Test
856     @SuppressWarnings("unchecked")
857     public void testInternalState_CursorNextNextRemoveByListSetByIterator() {
858         list.add((E) "A");
859         list.add((E) "B");
860         list.add((E) "C");
861 
862         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
863         assertEquals("A", c1.next());
864         assertEquals("B", c1.next());
865 
866         list.remove(1);
867 
868         assertTrue(c1.nextIndexValid);
869         assertEquals(1, c1.nextIndex);
870         assertNull(c1.current);
871         assertEquals("C", c1.next.value);
872         assertEquals("[A, C]", list.toString());
873 
874         assertThrows(IllegalStateException.class, () -> c1.set((E) "Z"));
875     }
876 
877     @Test
878     @SuppressWarnings("unchecked")
879     public void testInternalState_CursorNextNextRemoveIndex1ByList() {
880         list.add((E) "A");
881         list.add((E) "B");
882         list.add((E) "C");
883 
884         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
885         assertEquals("A", c1.next());
886         assertEquals("B", c1.next());
887 
888         assertEquals("B", list.remove(1));
889 
890         assertTrue(c1.nextIndexValid);
891         assertEquals(1, c1.nextIndex);
892         assertTrue(c1.currentRemovedByAnother);
893         assertNull(c1.current);
894         assertEquals("C", c1.next.value);
895 
896         assertEquals("[A, C]", list.toString());
897         c1.remove();  // works ok
898         assertEquals("[A, C]", list.toString());
899 
900         assertThrows(IllegalStateException.class, () -> c1.remove());
901     }
902 
903     @Test
904     @SuppressWarnings("unchecked")
905     public void testInternalState_CursorNextNextSetByIterator() {
906         list.add((E) "A");
907         list.add((E) "B");
908         list.add((E) "C");
909 
910         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
911         assertEquals("A", c1.next());
912         assertEquals("B", c1.next());
913 
914         c1.set((E) "Z");
915 
916         assertTrue(c1.nextIndexValid);
917         assertEquals(2, c1.nextIndex);
918         assertEquals("Z", c1.current.value);
919         assertEquals("C", c1.next.value);
920 
921         assertEquals("[A, Z, C]", list.toString());
922         c1.remove();  // works ok
923         assertEquals("[A, C]", list.toString());
924 
925         assertThrows(IllegalStateException.class, () -> c1.remove());
926     }
927 
928     @Test
929     @SuppressWarnings("unchecked")
930     public void testInternalState_CursorNextRemoveIndex1ByList() {
931         list.add((E) "A");
932         list.add((E) "B");
933         list.add((E) "C");
934 
935         final CursorableLinkedList.Cursor<E> c1 = list.cursor();
936         assertEquals("A", c1.next());
937 
938         assertEquals("B", list.remove(1));
939 
940         assertTrue(c1.nextIndexValid);
941         assertEquals(1, c1.nextIndex);
942         assertFalse(c1.currentRemovedByAnother);
943         assertEquals("A", c1.current.value);
944         assertEquals("C", c1.next.value);
945 
946         assertEquals("[A, C]", list.toString());
947         c1.remove();  // works ok
948         assertEquals("[C]", list.toString());
949 
950         assertThrows(IllegalStateException.class, () -> c1.remove());
951     }
952 
953     @Test
954     @SuppressWarnings("unchecked")
955     public void testIsEmpty() {
956         assertTrue(list.isEmpty());
957         list.add((E) "element");
958         assertFalse(list.isEmpty());
959         list.remove("element");
960         assertTrue(list.isEmpty());
961         list.add((E) "element");
962         assertFalse(list.isEmpty());
963         list.clear();
964         assertTrue(list.isEmpty());
965     }
966 
967     @Test
968     @SuppressWarnings("unchecked")
969     public void testIterator() {
970         list.add((E) "1");
971         list.add((E) "2");
972         list.add((E) "3");
973         list.add((E) "4");
974         list.add((E) "5");
975         Iterator<E> it = list.iterator();
976         assertTrue(it.hasNext());
977         assertEquals("1", it.next());
978         assertTrue(it.hasNext());
979         assertEquals("2", it.next());
980         assertTrue(it.hasNext());
981         assertEquals("3", it.next());
982         assertTrue(it.hasNext());
983         assertEquals("4", it.next());
984         assertTrue(it.hasNext());
985         assertEquals("5", it.next());
986         assertFalse(it.hasNext());
987 
988         it = list.iterator();
989         assertTrue(it.hasNext());
990         assertEquals("1", it.next());
991         it.remove();
992         assertEquals("[2, 3, 4, 5]", list.toString());
993         assertTrue(it.hasNext());
994         assertEquals("2", it.next());
995         it.remove();
996         assertEquals("[3, 4, 5]", list.toString());
997         assertTrue(it.hasNext());
998         assertEquals("3", it.next());
999         it.remove();
1000         assertEquals("[4, 5]", list.toString());
1001         assertTrue(it.hasNext());
1002         assertEquals("4", it.next());
1003         it.remove();
1004         assertEquals("[5]", list.toString());
1005         assertTrue(it.hasNext());
1006         assertEquals("5", it.next());
1007         it.remove();
1008         assertEquals("[]", list.toString());
1009         assertFalse(it.hasNext());
1010     }
1011 
1012     @Test
1013     @Override
1014     @SuppressWarnings("unchecked")
1015     public void testListIteratorAdd() {
1016         final ListIterator<E> it = list.listIterator();
1017         it.add((E) "1");
1018         assertEquals("[1]", list.toString());
1019         it.add((E) "3");
1020         assertEquals("[1, 3]", list.toString());
1021         it.add((E) "5");
1022         assertEquals("[1, 3, 5]", list.toString());
1023         assertEquals("5", it.previous());
1024         it.add((E) "4");
1025         assertEquals("[1, 3, 4, 5]", list.toString());
1026         assertEquals("4", it.previous());
1027         assertEquals("3", it.previous());
1028         it.add((E) "2");
1029         assertEquals("[1, 2, 3, 4, 5]", list.toString());
1030     }
1031 
1032     @Test
1033     @SuppressWarnings("unchecked")
1034     public void testListIteratorNavigation() {
1035         list.add((E) "1");
1036         list.add((E) "2");
1037         list.add((E) "3");
1038         list.add((E) "4");
1039         list.add((E) "5");
1040         final ListIterator<E> it = list.listIterator();
1041         assertTrue(it.hasNext());
1042         assertFalse(it.hasPrevious());
1043         assertEquals(-1, it.previousIndex());
1044         assertEquals(0, it.nextIndex());
1045         assertEquals("1", it.next());
1046         assertTrue(it.hasNext());
1047         assertTrue(it.hasPrevious());
1048         assertEquals(0, it.previousIndex());
1049         assertEquals(1, it.nextIndex());
1050         assertEquals("1", it.previous());
1051         assertTrue(it.hasNext());
1052         assertFalse(it.hasPrevious());
1053         assertEquals(-1, it.previousIndex());
1054         assertEquals(0, it.nextIndex());
1055         assertEquals("1", it.next());
1056         assertTrue(it.hasNext());
1057         assertTrue(it.hasPrevious());
1058         assertEquals(0, it.previousIndex());
1059         assertEquals(1, it.nextIndex());
1060         assertEquals("2", it.next());
1061         assertTrue(it.hasNext());
1062         assertTrue(it.hasPrevious());
1063         assertEquals(1, it.previousIndex());
1064         assertEquals(2, it.nextIndex());
1065         assertEquals("2", it.previous());
1066         assertTrue(it.hasNext());
1067         assertTrue(it.hasPrevious());
1068         assertEquals(0, it.previousIndex());
1069         assertEquals(1, it.nextIndex());
1070         assertEquals("2", it.next());
1071         assertTrue(it.hasNext());
1072         assertTrue(it.hasPrevious());
1073         assertEquals(1, it.previousIndex());
1074         assertEquals(2, it.nextIndex());
1075         assertEquals("3", it.next());
1076         assertTrue(it.hasNext());
1077         assertTrue(it.hasPrevious());
1078         assertEquals(2, it.previousIndex());
1079         assertEquals(3, it.nextIndex());
1080         assertEquals("4", it.next());
1081         assertTrue(it.hasNext());
1082         assertTrue(it.hasPrevious());
1083         assertEquals(3, it.previousIndex());
1084         assertEquals(4, it.nextIndex());
1085         assertEquals("5", it.next());
1086         assertFalse(it.hasNext());
1087         assertTrue(it.hasPrevious());
1088         assertEquals(4, it.previousIndex());
1089         assertEquals(5, it.nextIndex());
1090         assertEquals("5", it.previous());
1091         assertTrue(it.hasNext());
1092         assertTrue(it.hasPrevious());
1093         assertEquals(3, it.previousIndex());
1094         assertEquals(4, it.nextIndex());
1095         assertEquals("4", it.previous());
1096         assertTrue(it.hasNext());
1097         assertTrue(it.hasPrevious());
1098         assertEquals(2, it.previousIndex());
1099         assertEquals(3, it.nextIndex());
1100         assertEquals("3", it.previous());
1101         assertTrue(it.hasNext());
1102         assertTrue(it.hasPrevious());
1103         assertEquals(1, it.previousIndex());
1104         assertEquals(2, it.nextIndex());
1105         assertEquals("2", it.previous());
1106         assertTrue(it.hasNext());
1107         assertTrue(it.hasPrevious());
1108         assertEquals(0, it.previousIndex());
1109         assertEquals(1, it.nextIndex());
1110         assertEquals("1", it.previous());
1111         assertTrue(it.hasNext());
1112         assertFalse(it.hasPrevious());
1113         assertEquals(-1, it.previousIndex());
1114         assertEquals(0, it.nextIndex());
1115     }
1116 
1117     @Test
1118     @SuppressWarnings("unchecked")
1119     public void testListIteratorRemove() {
1120         list.add((E) "1");
1121         list.add((E) "2");
1122         list.add((E) "3");
1123         list.add((E) "4");
1124         list.add((E) "5");
1125 
1126         final ListIterator<E> it = list.listIterator();
1127         try {
1128             it.remove();
1129         } catch (final IllegalStateException e) {
1130             // expected
1131         }
1132         assertEquals("1", it.next());
1133         assertEquals("2", it.next());
1134         assertEquals("[1, 2, 3, 4, 5]", list.toString());
1135         it.remove();
1136         assertEquals("[1, 3, 4, 5]", list.toString());
1137         assertEquals("3", it.next());
1138         assertEquals("3", it.previous());
1139         assertEquals("1", it.previous());
1140         it.remove();
1141         assertEquals("[3, 4, 5]", list.toString());
1142         assertFalse(it.hasPrevious());
1143         assertEquals("3", it.next());
1144         it.remove();
1145         assertEquals("[4, 5]", list.toString());
1146         try {
1147             it.remove();
1148         } catch (final IllegalStateException e) {
1149             // expected
1150         }
1151         assertEquals("4", it.next());
1152         assertEquals("5", it.next());
1153         it.remove();
1154         assertEquals("[4]", list.toString());
1155         assertEquals("4", it.previous());
1156         it.remove();
1157         assertEquals("[]", list.toString());
1158     }
1159 
1160     @Test
1161     @Override
1162     @SuppressWarnings("unchecked")
1163     public void testListIteratorSet() {
1164         list.add((E) "1");
1165         list.add((E) "2");
1166         list.add((E) "3");
1167         list.add((E) "4");
1168         list.add((E) "5");
1169 
1170         final ListIterator<E> it = list.listIterator();
1171         assertEquals("1", it.next());
1172         it.set((E) "a");
1173         assertEquals("a", it.previous());
1174         it.set((E) "A");
1175         assertEquals("A", it.next());
1176         assertEquals("2", it.next());
1177         it.set((E) "B");
1178         assertEquals("3", it.next());
1179         assertEquals("4", it.next());
1180         it.set((E) "D");
1181         assertEquals("5", it.next());
1182         it.set((E) "E");
1183         assertEquals("[A, B, 3, D, E]", list.toString());
1184     }
1185 
1186     @Test
1187     @SuppressWarnings("unchecked")
1188     public void testLongSerialization() throws Exception {
1189         // recursive serialization will cause a stack
1190         // overflow exception with long lists
1191         for (int i = 0; i < 10000; i++) {
1192             list.add((E) Integer.valueOf(i));
1193         }
1194 
1195         final java.io.ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
1196         final java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(buf);
1197         out.writeObject(list);
1198         out.flush();
1199         out.close();
1200 
1201         final java.io.ByteArrayInputStream bufin = new java.io.ByteArrayInputStream(buf.toByteArray());
1202         final java.io.ObjectInputStream in = new java.io.ObjectInputStream(bufin);
1203         final Object list2 = in.readObject();
1204 
1205         assertNotSame(list, list2);
1206         assertEquals(list2, list);
1207         assertEquals(list, list2);
1208     }
1209 
1210     @Test
1211     @SuppressWarnings("unchecked")
1212     public void testRemove() {
1213         list.add((E) "1");
1214         list.add((E) "1");
1215         list.add((E) "2");
1216         list.add((E) "3");
1217         list.add((E) "4");
1218         list.add((E) "5");
1219         list.add((E) "2");
1220         list.add((E) "3");
1221         list.add((E) "4");
1222         list.add((E) "5");
1223         assertEquals("[1, 1, 2, 3, 4, 5, 2, 3, 4, 5]", list.toString());
1224         assertFalse(list.remove("6"));
1225         assertTrue(list.remove("5"));
1226         assertEquals("[1, 1, 2, 3, 4, 2, 3, 4, 5]", list.toString());
1227         assertTrue(list.remove("5"));
1228         assertEquals("[1, 1, 2, 3, 4, 2, 3, 4]", list.toString());
1229         assertFalse(list.remove("5"));
1230         assertTrue(list.remove("1"));
1231         assertEquals("[1, 2, 3, 4, 2, 3, 4]", list.toString());
1232         assertTrue(list.remove("1"));
1233         assertEquals("[2, 3, 4, 2, 3, 4]", list.toString());
1234         assertTrue(list.remove("2"));
1235         assertEquals("[3, 4, 2, 3, 4]", list.toString());
1236         assertTrue(list.remove("2"));
1237         assertEquals("[3, 4, 3, 4]", list.toString());
1238         assertTrue(list.remove("3"));
1239         assertEquals("[4, 3, 4]", list.toString());
1240         assertTrue(list.remove("3"));
1241         assertEquals("[4, 4]", list.toString());
1242         assertTrue(list.remove("4"));
1243         assertEquals("[4]", list.toString());
1244         assertTrue(list.remove("4"));
1245         assertEquals("[]", list.toString());
1246     }
1247 
1248     @Test
1249     @SuppressWarnings("unchecked")
1250     public void testRemoveAll() {
1251         list.add((E) "1");
1252         list.add((E) "2");
1253         list.add((E) "3");
1254         list.add((E) "4");
1255         list.add((E) "5");
1256 
1257         final HashSet<E> set = new HashSet<>();
1258         set.add((E) "A");
1259         set.add((E) "2");
1260         set.add((E) "C");
1261         set.add((E) "4");
1262         set.add((E) "D");
1263 
1264         assertTrue(list.removeAll(set));
1265         assertEquals("[1, 3, 5]", list.toString());
1266         assertFalse(list.removeAll(set));
1267     }
1268 
1269     @Test
1270     @SuppressWarnings("unchecked")
1271     public void testRemoveByIndex() {
1272         list.add((E) "1");
1273         list.add((E) "2");
1274         list.add((E) "3");
1275         list.add((E) "4");
1276         list.add((E) "5");
1277         assertEquals("[1, 2, 3, 4, 5]", list.toString());
1278         assertEquals("1", list.remove(0));
1279         assertEquals("[2, 3, 4, 5]", list.toString());
1280         assertEquals("3", list.remove(1));
1281         assertEquals("[2, 4, 5]", list.toString());
1282         assertEquals("4", list.remove(1));
1283         assertEquals("[2, 5]", list.toString());
1284         assertEquals("5", list.remove(1));
1285         assertEquals("[2]", list.toString());
1286         assertEquals("2", list.remove(0));
1287         assertEquals("[]", list.toString());
1288     }
1289 
1290     @Test
1291     @SuppressWarnings("unchecked")
1292     public void testRetainAll() {
1293         list.add((E) "1");
1294         list.add((E) "1");
1295         list.add((E) "2");
1296         list.add((E) "2");
1297         list.add((E) "3");
1298         list.add((E) "3");
1299         list.add((E) "4");
1300         list.add((E) "4");
1301         list.add((E) "5");
1302         list.add((E) "5");
1303 
1304         final HashSet<E> set = new HashSet<>();
1305         set.add((E) "A");
1306         set.add((E) "2");
1307         set.add((E) "C");
1308         set.add((E) "4");
1309         set.add((E) "D");
1310 
1311         assertTrue(list.retainAll(set));
1312         assertEquals("[2, 2, 4, 4]", list.toString());
1313         assertFalse(list.retainAll(set));
1314     }
1315 
1316     @Test
1317     @SuppressWarnings("unchecked")
1318     public void testSerialization() throws Exception {
1319         list.add((E) "A");
1320         list.add((E) "B");
1321         list.add((E) "C");
1322         list.add((E) "D");
1323         list.add((E) "E");
1324 
1325         final java.io.ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
1326         final java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(buf);
1327         out.writeObject(list);
1328         out.flush();
1329         out.close();
1330 
1331         final java.io.ByteArrayInputStream bufIn = new java.io.ByteArrayInputStream(buf.toByteArray());
1332         final java.io.ObjectInputStream in = new java.io.ObjectInputStream(bufIn);
1333         final Object list2 = in.readObject();
1334 
1335         assertNotSame(list, list2);
1336         assertEquals(list2, list);
1337         assertEquals(list, list2);
1338     }
1339 
1340     @Test
1341     @SuppressWarnings("unchecked")
1342     public void testSerializationWithOpenCursor() throws Exception {
1343         list.add((E) "A");
1344         list.add((E) "B");
1345         list.add((E) "C");
1346         list.add((E) "D");
1347         list.add((E) "E");
1348         final java.io.ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
1349         final java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(buf);
1350         out.writeObject(list);
1351         out.flush();
1352         out.close();
1353 
1354         final java.io.ByteArrayInputStream bufin = new java.io.ByteArrayInputStream(buf.toByteArray());
1355         final java.io.ObjectInputStream in = new java.io.ObjectInputStream(bufin);
1356         final Object list2 = in.readObject();
1357 
1358         assertNotSame(list, list2);
1359         assertEquals(list2, list);
1360         assertEquals(list, list2);
1361     }
1362 
1363     @Test
1364     @SuppressWarnings("unchecked")
1365     public void testSet() {
1366         list.add((E) "1");
1367         list.add((E) "2");
1368         list.add((E) "3");
1369         list.add((E) "4");
1370         list.add((E) "5");
1371         assertEquals("[1, 2, 3, 4, 5]", list.toString());
1372         list.set(0, (E) "A");
1373         assertEquals("[A, 2, 3, 4, 5]", list.toString());
1374         list.set(1, (E) "B");
1375         assertEquals("[A, B, 3, 4, 5]", list.toString());
1376         list.set(2, (E) "C");
1377         assertEquals("[A, B, C, 4, 5]", list.toString());
1378         list.set(3, (E) "D");
1379         assertEquals("[A, B, C, D, 5]", list.toString());
1380         list.set(4, (E) "E");
1381         assertEquals("[A, B, C, D, E]", list.toString());
1382     }
1383 
1384     @Test
1385     @SuppressWarnings("unchecked")
1386     public void testSubList() {
1387         list.add((E) "A");
1388         list.add((E) "B");
1389         list.add((E) "C");
1390         list.add((E) "D");
1391         list.add((E) "E");
1392 
1393         assertEquals("[A, B, C, D, E]", list.toString());
1394         assertEquals("[A, B, C, D, E]", list.subList(0, 5).toString());
1395         assertEquals("[B, C, D, E]", list.subList(1, 5).toString());
1396         assertEquals("[C, D, E]", list.subList(2, 5).toString());
1397         assertEquals("[D, E]", list.subList(3, 5).toString());
1398         assertEquals("[E]", list.subList(4, 5).toString());
1399         assertEquals("[]", list.subList(5, 5).toString());
1400     }
1401 
1402     @Test
1403     @SuppressWarnings("unchecked")
1404     public void testSubListAddBegin() {
1405         list.add((E) "A");
1406         list.add((E) "B");
1407         list.add((E) "C");
1408         list.add((E) "D");
1409         list.add((E) "E");
1410 
1411         final List<E> sublist = list.subList(0, 0);
1412         sublist.add((E) "a");
1413         assertEquals("[a, A, B, C, D, E]", list.toString());
1414         assertEquals("[a]", sublist.toString());
1415         sublist.add((E) "b");
1416         assertEquals("[a, b, A, B, C, D, E]", list.toString());
1417         assertEquals("[a, b]", sublist.toString());
1418     }
1419 
1420     @Test
1421     @SuppressWarnings("unchecked")
1422     public void testSubListAddEnd() {
1423         list.add((E) "A");
1424         list.add((E) "B");
1425         list.add((E) "C");
1426         list.add((E) "D");
1427         list.add((E) "E");
1428 
1429         final List<E> sublist = list.subList(5, 5);
1430         sublist.add((E) "F");
1431         assertEquals("[A, B, C, D, E, F]", list.toString());
1432         assertEquals("[F]", sublist.toString());
1433         sublist.add((E) "G");
1434         assertEquals("[A, B, C, D, E, F, G]", list.toString());
1435         assertEquals("[F, G]", sublist.toString());
1436     }
1437 
1438     @Test
1439     @SuppressWarnings("unchecked")
1440     public void testSubListAddMiddle() {
1441         list.add((E) "A");
1442         list.add((E) "B");
1443         list.add((E) "C");
1444         list.add((E) "D");
1445         list.add((E) "E");
1446 
1447         final List<E> sublist = list.subList(1, 3);
1448         sublist.add((E) "a");
1449         assertEquals("[A, B, C, a, D, E]", list.toString());
1450         assertEquals("[B, C, a]", sublist.toString());
1451         sublist.add((E) "b");
1452         assertEquals("[A, B, C, a, b, D, E]", list.toString());
1453         assertEquals("[B, C, a, b]", sublist.toString());
1454     }
1455 
1456     @Test
1457     @SuppressWarnings("unchecked")
1458     public void testSubListRemove() {
1459         list.add((E) "A");
1460         list.add((E) "B");
1461         list.add((E) "C");
1462         list.add((E) "D");
1463         list.add((E) "E");
1464 
1465         final List<E> sublist = list.subList(1, 4);
1466         assertEquals("[B, C, D]", sublist.toString());
1467         assertEquals("[A, B, C, D, E]", list.toString());
1468         sublist.remove("C");
1469         assertEquals("[B, D]", sublist.toString());
1470         assertEquals("[A, B, D, E]", list.toString());
1471         sublist.remove(1);
1472         assertEquals("[B]", sublist.toString());
1473         assertEquals("[A, B, E]", list.toString());
1474         sublist.clear();
1475         assertEquals("[]", sublist.toString());
1476         assertEquals("[A, E]", list.toString());
1477     }
1478 
1479     @Test
1480     @SuppressWarnings("unchecked")
1481     public void testToArray() {
1482         list.add((E) "1");
1483         list.add((E) "2");
1484         list.add((E) "3");
1485         list.add((E) "4");
1486         list.add((E) "5");
1487 
1488         final Object[] elts = list.toArray();
1489         assertEquals("1", elts[0]);
1490         assertEquals("2", elts[1]);
1491         assertEquals("3", elts[2]);
1492         assertEquals("4", elts[3]);
1493         assertEquals("5", elts[4]);
1494         assertEquals(5, elts.length);
1495 
1496         final String[] elts2 = list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
1497         assertEquals("1", elts2[0]);
1498         assertEquals("2", elts2[1]);
1499         assertEquals("3", elts2[2]);
1500         assertEquals("4", elts2[3]);
1501         assertEquals("5", elts2[4]);
1502         assertEquals(5, elts2.length);
1503 
1504         final String[] elts3 = new String[5];
1505         assertSame(elts3, list.toArray(elts3));
1506         assertEquals("1", elts3[0]);
1507         assertEquals("2", elts3[1]);
1508         assertEquals("3", elts3[2]);
1509         assertEquals("4", elts3[3]);
1510         assertEquals("5", elts3[4]);
1511         assertEquals(5, elts3.length);
1512 
1513         final String[] elts4 = new String[3];
1514         final String[] elts4b = list.toArray(elts4);
1515         assertNotSame(elts4, elts4b);
1516         assertEquals("1", elts4b[0]);
1517         assertEquals("2", elts4b[1]);
1518         assertEquals("3", elts4b[2]);
1519         assertEquals("4", elts4b[3]);
1520         assertEquals("5", elts4b[4]);
1521         assertEquals(5, elts4b.length);
1522     }
1523 
1524 //    public void testCreate() throws Exception {
1525 //        resetEmpty();
1526 //        writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CursorableLinkedList.emptyCollection.version4.obj");
1527 //        resetFull();
1528 //        writeExternalFormToDisk((java.io.Serializable) getCollection(), "src/test/resources/data/test/CursorableLinkedList.fullCollection.version4.obj");
1529 //    }
1530 
1531 }