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;
18  
19  import static org.apache.commons.collections4.functors.EqualPredicate.equalPredicate;
20  import static org.apache.commons.collections4.functors.TruePredicate.INSTANCE;
21  import static org.easymock.EasyMock.createMock;
22  import static org.easymock.EasyMock.expect;
23  import static org.easymock.EasyMock.replay;
24  import static org.junit.jupiter.api.Assertions.assertAll;
25  import static org.junit.jupiter.api.Assertions.assertEquals;
26  import static org.junit.jupiter.api.Assertions.assertFalse;
27  import static org.junit.jupiter.api.Assertions.assertNull;
28  import static org.junit.jupiter.api.Assertions.assertSame;
29  import static org.junit.jupiter.api.Assertions.assertThrows;
30  import static org.junit.jupiter.api.Assertions.assertTrue;
31  
32  import java.util.ArrayList;
33  import java.util.Arrays;
34  import java.util.Collection;
35  import java.util.Collections;
36  import java.util.Comparator;
37  import java.util.Dictionary;
38  import java.util.Enumeration;
39  import java.util.HashMap;
40  import java.util.Iterator;
41  import java.util.LinkedHashSet;
42  import java.util.List;
43  import java.util.ListIterator;
44  import java.util.Map;
45  import java.util.NoSuchElementException;
46  import java.util.Set;
47  import java.util.Vector;
48  
49  import org.apache.commons.collections4.iterators.ArrayIterator;
50  import org.apache.commons.collections4.iterators.EmptyIterator;
51  import org.apache.commons.collections4.iterators.EmptyListIterator;
52  import org.apache.commons.collections4.iterators.EmptyMapIterator;
53  import org.apache.commons.collections4.iterators.EmptyOrderedIterator;
54  import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator;
55  import org.apache.commons.collections4.iterators.EnumerationIterator;
56  import org.apache.commons.collections4.iterators.NodeListIterator;
57  import org.apache.commons.collections4.iterators.ObjectArrayIterator;
58  import org.apache.commons.collections4.iterators.ZippingIterator;
59  import org.apache.commons.collections4.map.EntrySetToMapIteratorAdapter;
60  import org.junit.jupiter.api.BeforeEach;
61  import org.junit.jupiter.api.Test;
62  import org.w3c.dom.Node;
63  import org.w3c.dom.NodeList;
64  
65  /**
66   * Tests for IteratorUtils.
67   */
68  public class IteratorUtilsTest {
69  
70      /**
71       * Collection of {@link Integer}s
72       */
73      private List<Integer> collectionA;
74  
75      /**
76       * Collection of even {@link Integer}s
77       */
78      private List<Integer> collectionEven;
79  
80      /**
81       * Collection of odd {@link Integer}s
82       */
83      private List<Integer> collectionOdd;
84  
85      private final Collection<Integer> emptyCollection = new ArrayList<>(1);
86  
87      private Iterable<Integer> iterableA;
88  
89      /**
90       * Creates a NodeList containing the specified nodes.
91       */
92      private NodeList createNodeList(final Node[] nodes) {
93          return new NodeList() {
94              @Override
95              public int getLength() {
96                  return nodes.length;
97              }
98  
99              @Override
100             public Node item(final int index) {
101                 return nodes[index];
102             }
103         };
104     }
105 
106     /**
107      * creates an array of four Node instances, mocked by EasyMock.
108      */
109     private Node[] createNodes() {
110         final Node node1 = createMock(Node.class);
111         final Node node2 = createMock(Node.class);
112         final Node node3 = createMock(Node.class);
113         final Node node4 = createMock(Node.class);
114         replay(node1);
115         replay(node2);
116         replay(node3);
117         replay(node4);
118 
119         return new Node[] { node1, node2, node3, node4 };
120     }
121 
122     /**
123      * Gets an immutable Iterator operating on the elements ["a", "b", "c", "d"].
124      */
125     private Iterator<String> getImmutableIterator() {
126         final List<String> list = new ArrayList<>();
127         list.add("a");
128         list.add("b");
129         list.add("c");
130         list.add("d");
131         return IteratorUtils.unmodifiableIterator(list.iterator());
132     }
133 
134     /**
135      * Gets an immutable ListIterator operating on the elements ["a", "b", "c", "d"].
136      */
137     private ListIterator<String> getImmutableListIterator() {
138         final List<String> list = new ArrayList<>();
139         list.add("a");
140         list.add("b");
141         list.add("c");
142         list.add("d");
143         return IteratorUtils.unmodifiableListIterator(list.listIterator());
144     }
145 
146     @BeforeEach
147     public void setUp() {
148         collectionA = new ArrayList<>();
149         collectionA.add(1);
150         collectionA.add(2);
151         collectionA.add(2);
152         collectionA.add(3);
153         collectionA.add(3);
154         collectionA.add(3);
155         collectionA.add(4);
156         collectionA.add(4);
157         collectionA.add(4);
158         collectionA.add(4);
159 
160         iterableA = collectionA;
161 
162         collectionEven = Arrays.asList(2, 4, 6, 8, 10, 12);
163         collectionOdd = Arrays.asList(1, 3, 5, 7, 9, 11);
164     }
165 
166     @Test
167     public void testArrayIterator() {
168         final Object[] objArray = { "a", "b", "c" };
169         ResettableIterator<Object> iterator = IteratorUtils.arrayIterator(objArray);
170         assertEquals("a", iterator.next());
171         assertEquals("b", iterator.next());
172         iterator.reset();
173         assertEquals("a", iterator.next());
174         assertAll(
175                 () -> assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayIterator(Integer.valueOf(0)),
176                         "Expecting NullPointerException"),
177                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.arrayIterator((Object[]) null),
178                         "Expecting NullPointerException")
179         );
180 
181         iterator = IteratorUtils.arrayIterator(objArray, 1);
182         assertEquals("b", iterator.next());
183 
184         assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, -1),
185                 "Expecting IndexOutOfBoundsException");
186 
187         iterator = IteratorUtils.arrayIterator(objArray, 3);
188         assertFalse(iterator.hasNext());
189         iterator.reset();
190 
191         assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, 4),
192                 "Expecting IndexOutOfBoundsException");
193 
194         iterator = IteratorUtils.arrayIterator(objArray, 2, 3);
195         assertEquals("c", iterator.next());
196         assertAll(
197                 () -> assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, 2, 4),
198                         "Expecting IndexOutOfBoundsException"),
199                 () -> assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, -1, 1),
200                         "Expecting IndexOutOfBoundsException"),
201                 () -> assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayIterator(objArray, 2, 1),
202                         "Expecting IllegalArgumentException")
203         );
204 
205         final int[] intArray = { 0, 1, 2 };
206         iterator = IteratorUtils.arrayIterator(intArray);
207         assertEquals(0, iterator.next());
208         assertEquals(1, iterator.next());
209         iterator.reset();
210         assertEquals(0, iterator.next());
211 
212         iterator = IteratorUtils.arrayIterator(intArray, 1);
213         assertEquals(1, iterator.next());
214 
215         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, -1),
216                 "Expecting IndexOutOfBoundsException");
217 
218         iterator = IteratorUtils.arrayIterator(intArray, 3);
219         assertFalse(iterator.hasNext());
220         iterator.reset();
221 
222         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, 4),
223                 "Expecting IndexOutOfBoundsException");
224 
225         iterator = IteratorUtils.arrayIterator(intArray, 2, 3);
226         assertEquals(2, iterator.next());
227         assertAll(
228                 () -> assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, 2, 4),
229                         "Expecting IndexOutOfBoundsException"),
230                 () -> assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, -1, 1),
231                         "Expecting IndexOutOfBoundsException"),
232                 () -> assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayIterator(intArray, 2, 1),
233                         "Expecting IllegalArgumentException")
234         );
235     }
236 
237     @Test
238     public void testArrayListIterator() {
239         final Object[] objArray = { "a", "b", "c", "d" };
240         ResettableListIterator<Object> iterator = IteratorUtils.arrayListIterator(objArray);
241         assertFalse(iterator.hasPrevious());
242         assertEquals(-1, iterator.previousIndex());
243         assertEquals(0, iterator.nextIndex());
244         assertEquals("a", iterator.next());
245         assertEquals("a", iterator.previous());
246         assertEquals("a", iterator.next());
247         assertEquals(0, iterator.previousIndex());
248         assertEquals(1, iterator.nextIndex());
249         assertEquals("b", iterator.next());
250         assertEquals("c", iterator.next());
251         assertEquals("d", iterator.next());
252         assertEquals(4, iterator.nextIndex()); // size of list
253         assertEquals(3, iterator.previousIndex());
254         assertAll(
255                 () -> assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayListIterator(Integer.valueOf(0)),
256                         "Expecting IllegalArgumentException"),
257                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.arrayListIterator((Object[]) null),
258                         "Expecting NullPointerException")
259         );
260 
261         iterator = IteratorUtils.arrayListIterator(objArray, 1);
262         assertEquals(-1, iterator.previousIndex());
263         assertFalse(iterator.hasPrevious());
264         assertEquals(0, iterator.nextIndex());
265         assertEquals("b", iterator.next());
266         assertEquals(0, iterator.previousIndex());
267         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, -1),
268                 "Expecting IndexOutOfBoundsException.");
269 
270         iterator = IteratorUtils.arrayListIterator(objArray, 3);
271         assertTrue(iterator.hasNext());
272 
273         final ResettableListIterator<Object> finalIterator = iterator;
274         assertAll(
275                 () -> assertThrows(NoSuchElementException.class, () -> finalIterator.previous(),
276                         "Expecting NoSuchElementException."),
277                 () -> assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, 5),
278                         "Expecting IndexOutOfBoundsException.")
279         );
280 
281         iterator = IteratorUtils.arrayListIterator(objArray, 2, 3);
282         assertEquals("c", iterator.next());
283         assertAll(
284                 () -> assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, 2, 5),
285                         "Expecting IndexOutOfBoundsException"),
286                 () -> assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, -1, 1),
287                         "Expecting IndexOutOfBoundsException"),
288                 () -> assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayListIterator(objArray, 2, 1),
289                         "Expecting IllegalArgumentException")
290         );
291 
292         final int[] intArray = { 0, 1, 2 };
293         iterator = IteratorUtils.arrayListIterator(intArray);
294         assertEquals(iterator.previousIndex(), -1);
295         assertFalse(iterator.hasPrevious());
296         assertEquals(0, iterator.nextIndex());
297         assertEquals(0, iterator.next());
298         assertEquals(0, iterator.previousIndex());
299         assertEquals(1, iterator.nextIndex());
300         assertEquals(1, iterator.next());
301         assertEquals(1, iterator.previousIndex());
302         assertEquals(2, iterator.nextIndex());
303         assertEquals(1, iterator.previous());
304         assertEquals(1, iterator.next());
305 
306         iterator = IteratorUtils.arrayListIterator(intArray, 1);
307         assertEquals(-1, iterator.previousIndex());
308         assertFalse(iterator.hasPrevious());
309         assertEquals(0, iterator.nextIndex());
310         assertEquals(1, iterator.next());
311         assertEquals(1, iterator.previous());
312         assertEquals(1, iterator.next());
313         assertEquals(0, iterator.previousIndex());
314         assertEquals(1, iterator.nextIndex());
315         assertEquals(2, iterator.next());
316         assertEquals(1, iterator.previousIndex());
317         assertEquals(2, iterator.nextIndex());
318         assertEquals(2, iterator.previous());
319         assertEquals(0, iterator.previousIndex());
320         assertEquals(1, iterator.nextIndex());
321 
322         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, -1),
323                 "Expecting IndexOutOfBoundsException");
324 
325         iterator = IteratorUtils.arrayListIterator(intArray, 3);
326         assertFalse(iterator.hasNext());
327 
328         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, 4),
329                 "Expecting IndexOutOfBoundsException");
330 
331         iterator = IteratorUtils.arrayListIterator(intArray, 2, 3);
332         assertFalse(iterator.hasPrevious());
333         assertEquals(-1, iterator.previousIndex());
334         assertEquals(2, iterator.next());
335         assertTrue(iterator.hasPrevious());
336         assertFalse(iterator.hasNext());
337         assertAll(
338                 () -> assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, 2, 4),
339                         "Expecting IndexOutOfBoundsException"),
340                 () -> assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, -1, 1),
341                         "Expecting IndexOutOfBoundsException"),
342                 () -> assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayListIterator(intArray, 2, 1),
343                         "Expecting IllegalArgumentException")
344         );
345     }
346 
347     @Test
348     public void testAsEnumerationNull() {
349         assertThrows(NullPointerException.class, () -> IteratorUtils.asEnumeration(null));
350     }
351 
352     @Test
353     public void testAsIterable() {
354         final List<Integer> list = new ArrayList<>();
355         list.add(Integer.valueOf(0));
356         list.add(Integer.valueOf(1));
357         list.add(Integer.valueOf(2));
358         final Iterator<Integer> iterator = list.iterator();
359 
360         final Iterable<Integer> iterable = IteratorUtils.asIterable(iterator);
361         int expected = 0;
362         for (final Integer actual : iterable) {
363             assertEquals(expected, actual.intValue());
364             ++expected;
365         }
366         // insure iteration occurred
367         assertTrue(expected > 0);
368 
369         // single use iterator
370         assertFalse(IteratorUtils.asIterable(iterator).iterator().hasNext(), "should not be able to iterate twice");
371     }
372 
373     @Test
374     public void testAsIterableNull() {
375         assertThrows(NullPointerException.class, () -> IteratorUtils.asIterable(null),
376                 "Expecting NullPointerException");
377     }
378 
379     @Test
380     public void testAsIterator() {
381         final Vector<String> vector = new Vector<>();
382         vector.addElement("zero");
383         vector.addElement("one");
384         final Enumeration<String> en = vector.elements();
385         assertTrue(IteratorUtils.asIterator(en) instanceof Iterator, "create instance fail");
386         assertThrows(NullPointerException.class, () -> IteratorUtils.asIterator(null));
387     }
388 
389     @Test
390     public void testAsIteratorNull() {
391         final Collection coll = new ArrayList();
392         coll.add("test");
393         final Vector<String> vector = new Vector<>();
394         vector.addElement("test");
395         vector.addElement("one");
396         final Enumeration<String> en = vector.elements();
397         assertTrue(IteratorUtils.asIterator(en, coll) instanceof Iterator, "create instance fail");
398         assertAll(
399                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.asIterator(null, coll)),
400                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.asIterator(en, null))
401         );
402     }
403 
404     @Test
405     public void testAsMultipleIterable() {
406         final List<Integer> list = new ArrayList<>();
407         list.add(Integer.valueOf(0));
408         list.add(Integer.valueOf(1));
409         list.add(Integer.valueOf(2));
410         final Iterator<Integer> iterator = list.iterator();
411 
412         final Iterable<Integer> iterable = IteratorUtils.asMultipleUseIterable(iterator);
413         int expected = 0;
414         for (final Integer actual : iterable) {
415             assertEquals(expected, actual.intValue());
416             ++expected;
417         }
418         // insure iteration occurred
419         assertTrue(expected > 0);
420 
421         // multiple use iterator
422         expected = 0;
423         for (final Integer actual : iterable) {
424             assertEquals(expected, actual.intValue());
425             ++expected;
426         }
427         // insure iteration occurred
428         assertTrue(expected > 0);
429     }
430 
431     @Test
432     public void testAsMultipleIterableNull() {
433         assertThrows(NullPointerException.class, () -> IteratorUtils.asMultipleUseIterable(null),
434                 "Expecting NullPointerException");
435     }
436 
437     @Test
438     public void testChainedIterator() {
439         final ArrayList arrayList = new ArrayList();
440         final Iterator iterator = arrayList.iterator();
441         assertTrue(IteratorUtils.chainedIterator(iterator) instanceof Iterator, "create instance fail");
442         final Collection<Iterator<?>> coll = new ArrayList();
443         assertTrue(IteratorUtils.chainedIterator(coll) instanceof Iterator, "create instance fail");
444     }
445 
446     /**
447      * Tests methods collatedIterator(...)
448      */
449     @Test
450     public void testCollatedIterator() {
451         assertAll(
452                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, collectionOdd.iterator(), null),
453                         "expecting NullPointerException"),
454                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, null, collectionEven.iterator()),
455                         "expecting NullPointerException")
456         );
457 
458         // natural ordering
459         Iterator<Integer> it = IteratorUtils.collatedIterator(null, collectionOdd.iterator(),
460                 collectionEven.iterator());
461 
462         List<Integer> result = IteratorUtils.toList(it);
463         assertEquals(12, result.size());
464 
465         final List<Integer> combinedList = new ArrayList<>(collectionOdd);
466         combinedList.addAll(collectionEven);
467         combinedList.sort(null);
468 
469         assertEquals(combinedList, result);
470 
471         it = IteratorUtils.collatedIterator(null, collectionOdd.iterator(), emptyCollection.iterator());
472         result = IteratorUtils.toList(it);
473         assertEquals(collectionOdd, result);
474 
475         final Comparator<Integer> reverseComparator = ComparatorUtils
476                 .reversedComparator(ComparatorUtils.<Integer>naturalComparator());
477 
478         Collections.reverse(collectionOdd);
479         Collections.reverse(collectionEven);
480         Collections.reverse(combinedList);
481 
482         it = IteratorUtils.collatedIterator(reverseComparator, collectionOdd.iterator(), collectionEven.iterator());
483         result = IteratorUtils.toList(it);
484         assertEquals(combinedList, result);
485     }
486 
487     @Test
488     public void testCollatedIteratorCollectionNull() {
489         final Collection<Iterator<?>> coll = new ArrayList<>();
490         coll.add(collectionOdd.iterator());
491         // natural ordering
492         final Iterator<?> it = IteratorUtils.collatedIterator(null, coll);
493         final List<?> result = IteratorUtils.toList(it);
494         assertEquals(6, result.size());
495         assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, (Collection<Iterator<?>>) null));
496     }
497 
498     @Test
499     public void testCollatedIteratorNull() {
500         final ArrayList arrayList = new ArrayList();
501         // natural ordering
502         Iterator<Integer> it = IteratorUtils.collatedIterator(null, collectionOdd.iterator(), collectionOdd.iterator(),
503                 collectionOdd.iterator());
504 
505         List<Integer> result = IteratorUtils.toList(it);
506         assertEquals(18, result.size());
507 
508         it = IteratorUtils.collatedIterator(null, collectionOdd.iterator());
509         result = IteratorUtils.toList(it);
510         assertEquals(collectionOdd, result);
511 
512         final Comparator<Integer> reverseComparator = ComparatorUtils
513                 .reversedComparator(ComparatorUtils.<Integer>naturalComparator());
514 
515         Collections.reverse(collectionOdd);
516 
517         it = IteratorUtils.collatedIterator(reverseComparator, collectionOdd.iterator());
518         result = IteratorUtils.toList(it);
519         assertEquals(collectionOdd, result);
520         assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, arrayList.iterator(), arrayList.listIterator(), null));
521     }
522 
523     /**
524      * Test empty iterator
525      */
526     @Test
527     public void testEmptyIterator() {
528         assertSame(EmptyIterator.INSTANCE, IteratorUtils.EMPTY_ITERATOR);
529         assertSame(EmptyIterator.RESETTABLE_INSTANCE, IteratorUtils.EMPTY_ITERATOR);
530         assertTrue(IteratorUtils.EMPTY_ITERATOR instanceof Iterator);
531         assertTrue(IteratorUtils.EMPTY_ITERATOR instanceof ResettableIterator);
532         assertFalse(IteratorUtils.EMPTY_ITERATOR instanceof OrderedIterator);
533         assertFalse(IteratorUtils.EMPTY_ITERATOR instanceof ListIterator);
534         assertFalse(IteratorUtils.EMPTY_ITERATOR instanceof MapIterator);
535         assertFalse(IteratorUtils.EMPTY_ITERATOR.hasNext());
536         IteratorUtils.EMPTY_ITERATOR.reset();
537         assertSame(IteratorUtils.EMPTY_ITERATOR, IteratorUtils.EMPTY_ITERATOR);
538         assertSame(IteratorUtils.EMPTY_ITERATOR, IteratorUtils.emptyIterator());
539         assertAll(
540                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ITERATOR.next()),
541                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ITERATOR.remove())
542         );
543     }
544 
545     /**
546      * Test empty list iterator
547      */
548     @Test
549     public void testEmptyListIterator() {
550         assertSame(EmptyListIterator.INSTANCE, IteratorUtils.EMPTY_LIST_ITERATOR);
551         assertSame(EmptyListIterator.RESETTABLE_INSTANCE, IteratorUtils.EMPTY_LIST_ITERATOR);
552         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof Iterator);
553         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof ListIterator);
554         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof ResettableIterator);
555         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof ResettableListIterator);
556         assertFalse(IteratorUtils.EMPTY_LIST_ITERATOR instanceof MapIterator);
557         assertFalse(IteratorUtils.EMPTY_LIST_ITERATOR.hasNext());
558         assertEquals(0, IteratorUtils.EMPTY_LIST_ITERATOR.nextIndex());
559         assertEquals(-1, IteratorUtils.EMPTY_LIST_ITERATOR.previousIndex());
560         IteratorUtils.EMPTY_LIST_ITERATOR.reset();
561         assertSame(IteratorUtils.EMPTY_LIST_ITERATOR, IteratorUtils.EMPTY_LIST_ITERATOR);
562         assertSame(IteratorUtils.EMPTY_LIST_ITERATOR, IteratorUtils.emptyListIterator());
563         assertAll(
564                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_LIST_ITERATOR.next()),
565                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_LIST_ITERATOR.previous()),
566                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_LIST_ITERATOR.remove()),
567                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.emptyListIterator().set(null)),
568                 () -> assertThrows(UnsupportedOperationException.class, () -> IteratorUtils.emptyListIterator().add(null))
569         );
570     }
571 
572     /**
573      * Test empty map iterator
574      */
575     @Test
576     @SuppressWarnings("unchecked")
577     public void testEmptyMapIterator() {
578         assertSame(EmptyMapIterator.INSTANCE, IteratorUtils.EMPTY_MAP_ITERATOR);
579         assertTrue(IteratorUtils.EMPTY_MAP_ITERATOR instanceof Iterator);
580         assertTrue(IteratorUtils.EMPTY_MAP_ITERATOR instanceof MapIterator);
581         assertTrue(IteratorUtils.EMPTY_MAP_ITERATOR instanceof ResettableIterator);
582         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR instanceof ListIterator);
583         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR instanceof OrderedIterator);
584         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR instanceof OrderedMapIterator);
585         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR.hasNext());
586         ((ResettableIterator<Object>) IteratorUtils.EMPTY_MAP_ITERATOR).reset();
587         assertSame(IteratorUtils.EMPTY_MAP_ITERATOR, IteratorUtils.EMPTY_MAP_ITERATOR);
588         assertSame(IteratorUtils.EMPTY_MAP_ITERATOR, IteratorUtils.emptyMapIterator());
589         assertAll(
590                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.next()),
591                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.remove()),
592                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.getKey()),
593                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.getValue()),
594                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.setValue(null))
595         );
596     }
597 
598     /**
599      * Test empty map iterator
600      */
601     @Test
602     @SuppressWarnings("unchecked")
603     public void testEmptyOrderedIterator() {
604         assertSame(EmptyOrderedIterator.INSTANCE, IteratorUtils.EMPTY_ORDERED_ITERATOR);
605         assertTrue(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof Iterator);
606         assertTrue(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof OrderedIterator);
607         assertTrue(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof ResettableIterator);
608         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof ListIterator);
609         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof MapIterator);
610         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR.hasNext());
611         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR.hasPrevious());
612         ((ResettableIterator<Object>) IteratorUtils.EMPTY_ORDERED_ITERATOR).reset();
613         assertSame(IteratorUtils.EMPTY_ORDERED_ITERATOR, IteratorUtils.EMPTY_ORDERED_ITERATOR);
614         assertSame(IteratorUtils.EMPTY_ORDERED_ITERATOR, IteratorUtils.emptyOrderedIterator());
615         assertAll(
616                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_ITERATOR.next()),
617                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_ITERATOR.previous()),
618                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_ITERATOR.remove())
619         );
620     }
621 
622     /**
623      * Test empty map iterator
624      */
625     @Test
626     @SuppressWarnings("unchecked")
627     public void testEmptyOrderedMapIterator() {
628         assertSame(EmptyOrderedMapIterator.INSTANCE, IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR);
629         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof Iterator);
630         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof MapIterator);
631         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof OrderedMapIterator);
632         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof ResettableIterator);
633         assertFalse(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof ListIterator);
634         assertFalse(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.hasNext());
635         assertFalse(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.hasPrevious());
636         ((ResettableIterator<Object>) IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR).reset();
637         assertSame(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR, IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR);
638         assertSame(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR, IteratorUtils.emptyOrderedMapIterator());
639         assertAll(
640                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.next()),
641                 () -> assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.previous()),
642                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.remove()),
643                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.getKey()),
644                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.getValue()),
645                 () -> assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.setValue(null))
646         );
647     }
648 
649     @Test
650     public void testFilteredIterator() {
651         final ArrayList arrayList = new ArrayList();
652         final Iterator iterator = arrayList.iterator();
653         assertAll(
654                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.filteredIterator(iterator, null)),
655                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.filteredIterator(null, null))
656         );
657     }
658 
659     @Test
660     public void testFilteredListIterator() {
661         final List arrayList = new ArrayList();
662         arrayList.add("test");
663         final Predicate predicate = INSTANCE;
664         assertTrue(IteratorUtils.filteredListIterator(arrayList.listIterator(), predicate) instanceof ListIterator,
665                 "create instance fail");
666         assertAll(
667                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.filteredListIterator(null, predicate)),
668                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.filteredListIterator(arrayList.listIterator(), null))
669         );
670     }
671 
672     @Test
673     public void testFind() {
674         Predicate<Number> testPredicate = equalPredicate((Number) 4);
675         Integer test = IteratorUtils.find(iterableA.iterator(), testPredicate);
676         assertEquals(4, (int) test);
677         testPredicate = equalPredicate((Number) 45);
678         test = IteratorUtils.find(iterableA.iterator(), testPredicate);
679         assertNull(test);
680         assertNull(IteratorUtils.find(null, testPredicate));
681 
682         assertThrows(NullPointerException.class, () -> IteratorUtils.find(iterableA.iterator(), null),
683                 "expecting NullPointerException");
684     }
685 
686     @Test
687     public void testFirstFromIterator() throws Exception {
688         // Iterator, entry exists
689         final Iterator<Integer> iterator = iterableA.iterator();
690         assertEquals(1, (int) IteratorUtils.first(iterator));
691     }
692 
693     @Test
694     public void testForEach() {
695         final List<Integer> listA = new ArrayList<>();
696         listA.add(1);
697 
698         final List<Integer> listB = new ArrayList<>();
699         listB.add(2);
700 
701         final Closure<List<Integer>> testClosure = ClosureUtils.invokerClosure("clear");
702         final Collection<List<Integer>> col = new ArrayList<>();
703         col.add(listA);
704         col.add(listB);
705         IteratorUtils.forEach(col.iterator(), testClosure);
706         assertTrue(listA.isEmpty() && listB.isEmpty());
707 
708         assertThrows(NullPointerException.class, () -> IteratorUtils.forEach(col.iterator(), null),
709                 "expecting NullPointerException");
710 
711         IteratorUtils.forEach(null, testClosure);
712 
713         // null should be OK
714         col.add(null);
715         IteratorUtils.forEach(col.iterator(), testClosure);
716     }
717 
718     @Test
719     public void testForEachButLast() {
720         final List<Integer> listA = new ArrayList<>();
721         listA.add(1);
722 
723         final List<Integer> listB = new ArrayList<>();
724         listB.add(2);
725 
726         final Closure<List<Integer>> testClosure = ClosureUtils.invokerClosure("clear");
727         final Collection<List<Integer>> col = new ArrayList<>();
728         col.add(listA);
729         col.add(listB);
730         List<Integer> last = IteratorUtils.forEachButLast(col.iterator(), testClosure);
731         assertTrue(listA.isEmpty() && !listB.isEmpty());
732         assertSame(listB, last);
733 
734         assertThrows(NullPointerException.class, () -> IteratorUtils.forEachButLast(col.iterator(), null),
735                 "expecting NullPointerException");
736 
737         IteratorUtils.forEachButLast(null, testClosure);
738 
739         // null should be OK
740         col.add(null);
741         col.add(null);
742         last = IteratorUtils.forEachButLast(col.iterator(), testClosure);
743         assertNull(last);
744     }
745 
746     @Test
747     public void testGetAtIndexFromIterator() throws Exception {
748         // Iterator, entry exists
749         Iterator<Integer> iterator = iterableA.iterator();
750         assertEquals(1, (int) IteratorUtils.get(iterator, 0));
751         iterator = iterableA.iterator();
752         assertEquals(2, (int) IteratorUtils.get(iterator, 1));
753 
754         // Iterator, non-existent entry
755         final Iterator<Integer> finalIterator = iterator;
756         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.get(finalIterator, 10),
757                 "Expecting IndexOutOfBoundsException.");
758 
759         assertFalse(iterator.hasNext());
760     }
761 
762     @Test
763     public void testGetIterator() {
764         final Object[] objArray = { "a", "b", "c" };
765         final Map<String, String> inMap = new HashMap<>();
766         final Node[] nodes = createNodes();
767         final NodeList nodeList = createNodeList(nodes);
768 
769         assertTrue(IteratorUtils.getIterator(null) instanceof EmptyIterator, "returns empty iterator when null passed");
770         assertTrue(IteratorUtils.getIterator(iterableA.iterator()) instanceof Iterator, "returns Iterator when Iterator directly ");
771         assertTrue(IteratorUtils.getIterator(iterableA) instanceof Iterator, "returns Iterator when iterable passed");
772         assertTrue(IteratorUtils.getIterator(objArray) instanceof ObjectArrayIterator,
773                 "returns ObjectArrayIterator when Object array passed");
774         assertTrue(IteratorUtils.getIterator(inMap) instanceof Iterator, "returns Iterator when Map passed");
775         assertTrue(IteratorUtils.getIterator(nodeList) instanceof NodeListIterator, "returns NodeListIterator when nodeList passed");
776         assertTrue(IteratorUtils.getIterator(new Vector().elements()) instanceof EnumerationIterator,
777                 "returns EnumerationIterator when Enumeration passed");
778         final Node node1 = createMock(Node.class);
779         assertTrue(IteratorUtils.getIterator(node1) instanceof NodeListIterator,
780                 "returns NodeListIterator when nodeList passed");
781         final Dictionary dic = createMock(Dictionary.class);
782         assertTrue(IteratorUtils.getIterator(dic) instanceof EnumerationIterator,
783                 "returns EnumerationIterator when Dictionary passed");
784         final int[] arr = new int[8];
785         assertTrue(IteratorUtils.getIterator(arr) instanceof ArrayIterator, "returns ArrayIterator when array passed");
786     }
787 
788     @Test
789     public void testIndexOf() {
790         Predicate<Number> testPredicate = equalPredicate((Number) 4);
791         int index = IteratorUtils.indexOf(iterableA.iterator(), testPredicate);
792         assertEquals(6, index);
793         testPredicate = equalPredicate((Number) 45);
794         index = IteratorUtils.indexOf(iterableA.iterator(), testPredicate);
795         assertEquals(-1, index);
796         assertEquals(-1, IteratorUtils.indexOf(null, testPredicate));
797 
798         assertThrows(NullPointerException.class, () -> IteratorUtils.indexOf(iterableA.iterator(), null),
799                 "expecting NullPointerException");
800     }
801 
802     @Test
803     public void testLoopingIterator() {
804         final ArrayList arrayList = new ArrayList();
805         arrayList.add("test");
806         final Collection coll = new ArrayList();
807         coll.add("test");
808         final Iterator iterator = arrayList.iterator();
809         assertTrue(IteratorUtils.loopingIterator(coll) instanceof ResettableIterator, "create instance fail");
810         assertThrows(NullPointerException.class, () -> IteratorUtils.loopingIterator(null));
811     }
812 
813     @Test
814     public void testLoopingListIterator() {
815         final ArrayList arrayList = new ArrayList();
816         arrayList.add("test");
817         final Iterator iterator = arrayList.iterator();
818         assertTrue(IteratorUtils.loopingListIterator(arrayList) instanceof ResettableIterator, "create instance fail");
819         assertThrows(NullPointerException.class, () -> IteratorUtils.loopingListIterator(null));
820     }
821 
822     /**
823      * Tests method nodeListIterator(Node)
824      */
825     @Test
826     public void testNodeIterator() {
827         final Node[] nodes = createNodes();
828         final NodeList nodeList = createNodeList(nodes);
829         final Node parentNode = createMock(Node.class);
830         expect(parentNode.getChildNodes()).andStubReturn(nodeList);
831         replay(parentNode);
832 
833         final Iterator<Node> iterator = IteratorUtils.nodeListIterator(parentNode);
834         int expectedNodeIndex = 0;
835         for (final Node actual : IteratorUtils.asIterable(iterator)) {
836             assertEquals(nodes[expectedNodeIndex], actual);
837             ++expectedNodeIndex;
838         }
839 
840         // insure iteration occurred
841         assertTrue(expectedNodeIndex > 0);
842 
843         // single use iterator
844         assertFalse(IteratorUtils.asIterable(iterator).iterator().hasNext(), "should not be able to iterate twice");
845 
846         assertThrows(NullPointerException.class, () -> IteratorUtils.nodeListIterator((Node) null),
847                 "Expecting NullPointerException");
848     }
849 
850     /**
851      * Tests method nodeListIterator(NodeList)
852      */
853     @Test
854     public void testNodeListIterator() {
855         final Node[] nodes = createNodes();
856         final NodeList nodeList = createNodeList(nodes);
857 
858         final Iterator<Node> iterator = IteratorUtils.nodeListIterator(nodeList);
859         int expectedNodeIndex = 0;
860         for (final Node actual : IteratorUtils.asIterable(iterator)) {
861             assertEquals(nodes[expectedNodeIndex], actual);
862             ++expectedNodeIndex;
863         }
864 
865         // insure iteration occurred
866         assertTrue(expectedNodeIndex > 0);
867 
868         // single use iterator
869         assertFalse(IteratorUtils.asIterable(iterator).iterator().hasNext(), "should not be able to iterate twice");
870 
871         assertThrows(NullPointerException.class, () -> IteratorUtils.nodeListIterator((NodeList) null),
872                 "Expecting NullPointerException");
873     }
874 
875     @Test
876     public void testObjectGraphIterator() {
877         assertTrue(IteratorUtils.objectGraphIterator(null, null) instanceof Iterator, "create instance fail");
878     }
879 
880     @Test
881     public void testPeekingIterator() {
882         final ArrayList arrayList = new ArrayList();
883         final Iterator iterator = arrayList.iterator();
884         assertTrue(IteratorUtils.peekingIterator(iterator) instanceof Iterator, "create instance fail");
885         assertThrows(NullPointerException.class, () -> IteratorUtils.peekingIterator(null));
886     }
887 
888     @Test
889     public void testPushBackIterator() {
890         final ArrayList arrayList = new ArrayList();
891         final Iterator iterator = arrayList.iterator();
892         assertTrue(IteratorUtils.pushbackIterator(iterator) instanceof Iterator, "create instance fail");
893         assertThrows(NullPointerException.class, () -> IteratorUtils.pushbackIterator(null));
894     }
895 
896     @Test
897     public void testSingletonIterator() {
898         assertTrue(IteratorUtils.singletonIterator(new Object()) instanceof ResettableIterator, "create instance fail");
899     }
900 
901     @Test
902     public void testSingletonListIterator() {
903         assertTrue(IteratorUtils.singletonListIterator(new Object()) instanceof Iterator, "create instance fail");
904     }
905 
906     @Test
907     public void testToArray() {
908         final List<Object> list = new ArrayList<>();
909         list.add(Integer.valueOf(1));
910         list.add("Two");
911         list.add(null);
912         final Object[] result = IteratorUtils.toArray(list.iterator());
913         assertEquals(list, Arrays.asList(result));
914 
915         assertThrows(NullPointerException.class, () -> IteratorUtils.toArray(null),
916                 "Expecting NullPointerException");
917     }
918 
919     @Test
920     public void testToArray2() {
921         final List<String> list = new ArrayList<>();
922         list.add("One");
923         list.add("Two");
924         list.add(null);
925         final String[] result = IteratorUtils.toArray(list.iterator(), String.class);
926         assertEquals(list, Arrays.asList(result));
927         assertAll(
928                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.toArray(list.iterator(), null),
929                         "Expecting NullPointerException"),
930                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.toArray(null, String.class),
931                         "Expecting NullPointerException")
932         );
933     }
934 
935     @Test
936     public void testToList() {
937         final List<Object> list = new ArrayList<>();
938         list.add(Integer.valueOf(1));
939         list.add("Two");
940         list.add(null);
941         final List<Object> result = IteratorUtils.toList(list.iterator());
942         assertEquals(list, result);
943         // add
944         assertAll(
945                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.toList(null, 10),
946                         "Expecting NullPointerException"),
947                 () -> assertThrows(IllegalArgumentException.class, () -> IteratorUtils.toList(list.iterator(), -1),
948                         "Expecting IllegalArgumentException")
949         );
950     }
951 
952     @Test
953     public void testToListIterator() {
954         final List<Integer> list = new ArrayList<>();
955         list.add(Integer.valueOf(0));
956         list.add(Integer.valueOf(1));
957         list.add(Integer.valueOf(2));
958         final Iterator<Integer> iterator = list.iterator();
959 
960         final ListIterator<Integer> liItr = IteratorUtils.toListIterator(iterator);
961         int expected = 0;
962         while (liItr.hasNext()) {
963             assertEquals(expected, liItr.next().intValue());
964             ++expected;
965         }
966     }
967 
968     @Test
969     public void testToListIteratorNull() {
970         assertThrows(NullPointerException.class, () -> IteratorUtils.toListIterator(null),
971                 "Expecting NullPointerException");
972     }
973 
974     @Test
975     public void testTransformedIterator() {
976         final ArrayList arrayList = new ArrayList();
977         final Iterator iterator = arrayList.iterator();
978         assertAll(
979                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.transformedIterator(iterator, null)),
980                 () -> assertThrows(NullPointerException.class, () -> IteratorUtils.transformedIterator(null, null))
981         );
982     }
983 
984     /**
985      * Test remove() for an immutable Iterator.
986      */
987     @Test
988     public void testUnmodifiableIteratorImmutability() {
989         final Iterator<String> iterator = getImmutableIterator();
990 
991         assertThrows(UnsupportedOperationException.class, () -> iterator.remove(),
992                 "remove() should throw an UnsupportedOperationException");
993 
994         iterator.next();
995 
996         assertThrows(UnsupportedOperationException.class, () -> iterator.remove(),
997                 "remove() should throw an UnsupportedOperationException");
998     }
999 
1000     /**
1001      * Test next() and hasNext() for an immutable Iterator.
1002      */
1003     @Test
1004     public void testUnmodifiableIteratorIteration() {
1005         final Iterator<String> iterator = getImmutableIterator();
1006 
1007         assertTrue(iterator.hasNext());
1008 
1009         assertEquals("a", iterator.next());
1010 
1011         assertTrue(iterator.hasNext());
1012 
1013         assertEquals("b", iterator.next());
1014 
1015         assertTrue(iterator.hasNext());
1016 
1017         assertEquals("c", iterator.next());
1018 
1019         assertTrue(iterator.hasNext());
1020 
1021         assertEquals("d", iterator.next());
1022 
1023         assertFalse(iterator.hasNext());
1024     }
1025 
1026     /**
1027      * Test remove() for an immutable ListIterator.
1028      */
1029     @Test
1030     public void testUnmodifiableListIteratorImmutability() {
1031         final ListIterator<String> listIterator = getImmutableListIterator();
1032         assertAll(
1033                 () -> assertThrows(UnsupportedOperationException.class, () -> listIterator.remove(),
1034                         "remove() should throw an UnsupportedOperationException"),
1035                 () -> assertThrows(UnsupportedOperationException.class, () -> listIterator.set("a"),
1036                         "set(Object) should throw an UnsupportedOperationException"),
1037                 () -> assertThrows(UnsupportedOperationException.class, () -> listIterator.add("a"),
1038                         "add(Object) should throw an UnsupportedOperationException")
1039         );
1040 
1041         listIterator.next();
1042         assertAll(
1043                 () -> assertThrows(UnsupportedOperationException.class, () -> listIterator.remove(),
1044                         "remove() should throw an UnsupportedOperationException"),
1045                 () -> assertThrows(UnsupportedOperationException.class, () -> listIterator.set("a"),
1046                         "set(Object) should throw an UnsupportedOperationException"),
1047                 () -> assertThrows(UnsupportedOperationException.class, () -> listIterator.add("a"),
1048                         "add(Object) should throw an UnsupportedOperationException")
1049         );
1050     }
1051 
1052     /**
1053      * Test next(), hasNext(), previous() and hasPrevious() for an immutable ListIterator.
1054      */
1055     @Test
1056     public void testUnmodifiableListIteratorIteration() {
1057         final ListIterator<String> listIterator = getImmutableListIterator();
1058 
1059         assertFalse(listIterator.hasPrevious());
1060         assertTrue(listIterator.hasNext());
1061 
1062         assertEquals("a", listIterator.next());
1063 
1064         assertTrue(listIterator.hasPrevious());
1065         assertTrue(listIterator.hasNext());
1066 
1067         assertEquals("b", listIterator.next());
1068 
1069         assertTrue(listIterator.hasPrevious());
1070         assertTrue(listIterator.hasNext());
1071 
1072         assertEquals("c", listIterator.next());
1073 
1074         assertTrue(listIterator.hasPrevious());
1075         assertTrue(listIterator.hasNext());
1076 
1077         assertEquals("d", listIterator.next());
1078 
1079         assertTrue(listIterator.hasPrevious());
1080         assertFalse(listIterator.hasNext());
1081 
1082         assertEquals("d", listIterator.previous());
1083 
1084         assertTrue(listIterator.hasPrevious());
1085         assertTrue(listIterator.hasNext());
1086 
1087         assertEquals("c", listIterator.previous());
1088 
1089         assertTrue(listIterator.hasPrevious());
1090         assertTrue(listIterator.hasNext());
1091 
1092         assertEquals("b", listIterator.previous());
1093 
1094         assertTrue(listIterator.hasPrevious());
1095         assertTrue(listIterator.hasNext());
1096 
1097         assertEquals("a", listIterator.previous());
1098 
1099         assertFalse(listIterator.hasPrevious());
1100         assertTrue(listIterator.hasNext());
1101     }
1102 
1103     @Test
1104     public void testUnmodifiableMapIterator() {
1105         final Set<?> set = new LinkedHashSet<>();
1106         final MapIterator iterator = new EntrySetToMapIteratorAdapter(set);
1107         assertTrue(IteratorUtils.unmodifiableMapIterator(iterator) instanceof MapIterator, "create instance fail");
1108         assertThrows(NullPointerException.class, () -> IteratorUtils.unmodifiableMapIterator(null));
1109     }
1110 
1111     @Test
1112     public void testZippingIterator() {
1113         final ArrayList arrayList = new ArrayList();
1114         final Iterator iterator = arrayList.iterator();
1115         assertTrue(IteratorUtils.zippingIterator(iterator, iterator, iterator) instanceof ZippingIterator, "create instance fail");
1116         assertTrue(IteratorUtils.zippingIterator(iterator, iterator) instanceof ZippingIterator, "create instance fail");
1117     }
1118 
1119 }