@Override
  @Test
  public void listIterator() {
    super.listIterator();
    CompositeFastList<String> composite = new CompositeFastList<String>();
    FastList<String> firstBit = FastList.newListWith("one", "two");
    FastList<String> secondBit = FastList.newListWith("three");
    composite.addAll(firstBit);
    composite.addAll(secondBit);

    ListIterator<String> listIterator = composite.listIterator();
    listIterator.add("four");
    Verify.assertSize(4, composite);
    Assert.assertTrue(listIterator.hasNext());
    String element = listIterator.next();

    Assert.assertEquals("one", element);

    String element3 = listIterator.next();

    Assert.assertEquals("two", element3);

    String element2 = listIterator.previous();
    Assert.assertEquals("two", element2);

    String element1 = listIterator.next();

    Assert.assertEquals("two", element1);

    listIterator.remove();

    Verify.assertSize(3, composite);
  }
  @Test
  public void removingFromIteratorIsCool() {
    CompositeFastList<String> undertest = new CompositeFastList<String>();
    undertest.addAll(FastList.newListWith("a"));
    undertest.addAll(FastList.newListWith("b", "c", "d"));

    Iterator<String> iterator1 = undertest.iterator();
    iterator1.next();
    iterator1.next();
    iterator1.next();
    iterator1.remove();
    Assert.assertEquals("d", iterator1.next());
    Assert.assertEquals(FastList.newListWith("a", "b", "d"), undertest);

    Iterator<String> iterator2 = undertest.iterator();
    iterator2.next();
    iterator2.next();
    iterator2.remove();
    Assert.assertEquals(FastList.newListWith("a", "d"), undertest);

    Iterator<String> iterator3 = undertest.iterator();
    iterator3.next();
    iterator3.remove();
    Assert.assertEquals(FastList.newListWith("d"), undertest);
    iterator3.next();
    iterator3.remove();
    Assert.assertEquals(FastList.newList(), undertest);
  }
 @Test
 public void testContainsAll() {
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("3", "B", "3", "B"));
   Assert.assertTrue(list.containsAll(FastList.newList().with("2", "B")));
 }
 @Override
 @Test
 public void retainAll() {
   super.retainAll();
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("3", "B", "3", "B"));
   list.retainAll(FastList.newList().with("2", "B"));
   Verify.assertSize(3, list);
 }
 @Override
 @Test
 public void clear() {
   super.clear();
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("3", "B", "3", "B"));
   list.clear();
   Assert.assertTrue(list.isEmpty());
   Assert.assertEquals(0, list.size());
 }
 @Override
 @Test
 public void toArray() {
   super.toArray();
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(Lists.mutable.<String>of());
   list.addAll(FastList.newListWith("3", "B", "3", "B"));
   list.addAll(Lists.mutable.<String>of());
   Assert.assertArrayEquals(new String[] {"1", "2", "3", "4", "3", "B", "3", "B"}, list.toArray());
 }
 @Override
 @Test
 public void lastIndexOf() {
   super.lastIndexOf();
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("3", "B", "3", "B"));
   Assert.assertEquals(6, list.lastIndexOf("3"));
   Assert.assertEquals(3, list.lastIndexOf("4"));
   Assert.assertEquals(-1, list.lastIndexOf("missing"));
 }
 @Override
 @Test
 public void collectIf() {
   Assert.assertEquals(
       FastList.newListWith("1", "2", "3"),
       MultiReaderFastList.newListWith(1, 2, 3)
           .collectIf(Integer.class::isInstance, String::valueOf));
   Assert.assertEquals(
       FastList.newListWith("1", "2", "3"),
       MultiReaderFastList.newListWith(1, 2, 3)
           .collectIf(Integer.class::isInstance, String::valueOf, FastList.newList()));
 }
 @Test
 public void testRemoveWithIndex() {
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("3", "B", "3", "B"));
   Assert.assertEquals("1", list.remove(0));
   Verify.assertSize(7, list);
   Assert.assertEquals("2", list.getFirst());
   Assert.assertEquals("B", list.remove(6));
   Verify.assertSize(6, list);
   Assert.assertEquals("3", list.getLast());
 }
 @Override
 @Test
 public void reverseThis() {
   super.reverseThis();
   CompositeFastList<Integer> composite = new CompositeFastList<Integer>();
   composite.addAll(FastList.newListWith(9, 8, 7));
   composite.addAll(FastList.newListWith(6, 5, 4));
   composite.addAll(FastList.newListWith(3, 2, 1));
   CompositeFastList<Integer> reversed = composite.reverseThis();
   Assert.assertSame(composite, reversed);
   Assert.assertEquals(Interval.oneTo(9), reversed);
 }
  @Test
  public void set_bugFix_off_by_one_error() {
    CompositeFastList<Integer> compositeList = new CompositeFastList<Integer>();
    MutableList<Integer> list1 = FastList.newListWith(1, 2, 3);
    MutableList<Integer> list2 = FastList.newListWith(4, 5);
    MutableList<Integer> list3 = FastList.newList();

    compositeList.addAll(list1);
    compositeList.addAll(list2);
    compositeList.addAll(list3);

    Assert.assertEquals(Integer.valueOf(4), compositeList.get(3));
    Assert.assertEquals(Integer.valueOf(4), compositeList.set(3, 99));
    Assert.assertEquals(Integer.valueOf(99), compositeList.get(3));
  }
 @Override
 @Test
 public void set() {
   super.set();
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("A", "B", "C", "B"));
   Assert.assertEquals("1", list.set(0, "NEW"));
   Verify.assertSize(8, list);
   Assert.assertEquals("NEW", list.getFirst());
   Assert.assertEquals("2", list.get(1));
   Assert.assertEquals("B", list.set(7, "END"));
   Verify.assertSize(8, list);
   Assert.assertEquals("END", list.getLast());
 }
 @Override
 @Test
 public void collect() {
   MutableList<Boolean> list = MultiReaderFastList.newListWith(Boolean.TRUE, Boolean.FALSE, null);
   MutableList<String> newCollection = list.collect(String::valueOf);
   Assert.assertEquals(FastList.newListWith("true", "false", "null"), newCollection);
 }
  @Test
  public void withWritelockAndDelegate() {
    MultiReaderFastList<Integer> list = MultiReaderFastList.newList(2);
    AtomicReference<MutableList<?>> delegateList = new AtomicReference<>();
    AtomicReference<MutableList<?>> subLists = new AtomicReference<>();
    AtomicReference<Iterator<?>> iterator = new AtomicReference<>();
    AtomicReference<Iterator<?>> listIterator = new AtomicReference<>();
    AtomicReference<Iterator<?>> listIteratorWithPosition = new AtomicReference<>();
    list.withWriteLockAndDelegate(
        delegate -> {
          delegate.add(1);
          delegate.add(2);
          delegate.add(3);
          delegate.add(4);
          delegateList.set(delegate);
          subLists.set(delegate.subList(1, 3));
          iterator.set(delegate.iterator());
          listIterator.set(delegate.listIterator());
          listIteratorWithPosition.set(delegate.listIterator(3));
        });
    Assert.assertEquals(FastList.newListWith(1, 2, 3, 4), list);

    this.assertIteratorThrows(delegateList.get());
    this.assertIteratorThrows(subLists.get());
    this.assertIteratorThrows(iterator.get());
    this.assertIteratorThrows(listIterator.get());
    this.assertIteratorThrows(listIteratorWithPosition.get());
  }
 @Test
 public void testAddWithIndex() {
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("A", "B", "C", "B"));
   list.add(3, "NEW");
   Verify.assertSize(9, list);
   Assert.assertEquals("NEW", list.get(3));
   Assert.assertEquals("4", list.get(4));
   list.add(0, "START");
   Verify.assertSize(10, list);
   Assert.assertEquals("START", list.getFirst());
   list.add(10, "END");
   Verify.assertSize(11, list);
   Assert.assertEquals("END", list.getLast());
 }
 @Override
 @Test
 public void forEach() {
   MutableList<Integer> result = FastList.newList();
   MutableList<Integer> collection = MultiReaderFastList.newListWith(1, 2, 3, 4);
   collection.forEach(CollectionAddProcedure.on(result));
   Assert.assertEquals(FastList.newListWith(1, 2, 3, 4), result);
 }
 @Override
 @Test
 public void forEachWith() {
   MutableList<Integer> result = FastList.newList();
   MutableList<Integer> collection = MultiReaderFastList.newListWith(1, 2, 3, 4);
   collection.forEachWith((argument1, argument2) -> result.add(argument1 + argument2), 0);
   Assert.assertEquals(FastList.newListWith(1, 2, 3, 4), result);
 }
 @Test
 public void forEachInBoth() {
   MutableList<Pair<String, String>> list = MultiReaderFastList.newList();
   MutableList<String> list1 = MultiReaderFastList.newListWith("1", "2");
   MutableList<String> list2 = MultiReaderFastList.newListWith("a", "b");
   ListIterate.forEachInBoth(
       list1, list2, (argument1, argument2) -> list.add(Tuples.pair(argument1, argument2)));
   Assert.assertEquals(FastList.newListWith(Tuples.pair("1", "a"), Tuples.pair("2", "b")), list);
 }
 @Test
 public void testGet() {
   MutableList<String> list = new CompositeFastList<String>();
   list.addAll(FastList.newListWith("1", "2", "3", "4"));
   list.addAll(FastList.newListWith("A", "B", "C", "B"));
   list.addAll(FastList.newListWith("Cat", "Dog", "Mouse", "Bird"));
   Assert.assertEquals("1", list.get(0));
   Assert.assertEquals("2", list.get(1));
   Assert.assertEquals("A", list.get(4));
   Assert.assertEquals("4", list.get(3));
   Assert.assertEquals("Cat", list.get(8));
   Assert.assertEquals("Bird", list.get(11));
   Verify.assertThrows(
       IndexOutOfBoundsException.class,
       () -> {
         list.get(12);
       });
 }
  @Test
  public void testHashCode() {
    CompositeFastList<String> composite = new CompositeFastList<String>();
    MutableList<String> list = FastList.newList();
    Verify.assertEqualsAndHashCode(composite, list);

    MutableList<String> list2 = FastList.newListWith("one", "two", "three");

    CompositeFastList<String> composite2 = new CompositeFastList<String>();
    MutableList<String> firstBit = FastList.newListWith("one", "two");
    MutableList<String> secondBit = FastList.newListWith("three");
    composite2.addAll(firstBit);
    composite2.addAll(secondBit);

    Verify.assertEqualsAndHashCode(list2, composite2);

    MutableList<String> list1 = FastList.newListWith("one", null, "three");

    CompositeFastList<String> composite1 = new CompositeFastList<String>();
    MutableList<String> firstBit1 = FastList.newListWith("one", null);
    MutableList<String> secondBit1 = FastList.newListWith("three");
    composite1.addAll(firstBit1);
    composite1.addAll(secondBit1);

    Verify.assertEqualsAndHashCode(list1, composite1);
  }
 @Test
 public void fastListNewWith() {
   Assert.assertEquals(
       FastList.newListWith("Alice", "Bob", "Cooper", "Dio"),
       MultiReaderFastList.newListWith("Alice", "Bob", "Cooper", "Dio"));
 }