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