@Test
  public void newListWithCollection() {
    Verify.assertEmpty(MultiReaderFastList.newList(Lists.fixedSize.of()));
    Verify.assertEmpty(MultiReaderFastList.newList(Sets.fixedSize.of()));
    Verify.assertEmpty(MultiReaderFastList.newList(FastList.newList()));
    Verify.assertEmpty(MultiReaderFastList.newList(FastList.newList(4)));

    MutableList<Integer> setToList =
        MultiReaderFastList.newList(UnifiedSet.newSetWith(1, 2, 3, 4, 5));
    Verify.assertNotEmpty(setToList);
    Verify.assertSize(5, setToList);
    Verify.assertContainsAll(setToList, 1, 2, 3, 4, 5);

    MutableList<Integer> arrayListToList =
        MultiReaderFastList.newList(Lists.fixedSize.of(1, 2, 3, 4, 5));
    Verify.assertNotEmpty(arrayListToList);
    Verify.assertSize(5, arrayListToList);
    Verify.assertStartsWith(arrayListToList, 1, 2, 3, 4, 5);

    MutableList<Integer> fastListToList =
        MultiReaderFastList.newList(FastList.<Integer>newList().with(1, 2, 3, 4, 5));
    Verify.assertNotEmpty(fastListToList);
    Verify.assertSize(5, fastListToList);
    Verify.assertStartsWith(fastListToList, 1, 2, 3, 4, 5);
  }
  @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 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 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 containsAll() {
   MutableList<Integer> list = this.newWith(1, 2, 3, 4, 5, null);
   Assert.assertTrue(list.containsAll(Lists.fixedSize.of(1, 3, 5, null)));
   Assert.assertFalse(list.containsAll(Lists.fixedSize.of(2, null, 6)));
   Assert.assertTrue(list.containsAll(FastList.<Integer>newList().with(1, 3, 5, null)));
   Assert.assertFalse(list.containsAll(FastList.<Integer>newList().with(2, null, 6)));
 }
 @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"));
 }
 @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);
 }
 @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()));
 }
 @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());
 }
  @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));
  }
 @Test
 public void addAllAtIndexEmpty() {
   MutableList<Integer> integers = this.newWith(5);
   integers.addAll(0, Lists.fixedSize.of());
   Verify.assertSize(1, integers);
   Verify.assertStartsWith(integers, 5);
   integers.addAll(0, FastList.newList(4));
   Verify.assertSize(1, integers);
   Verify.assertStartsWith(integers, 5);
   integers.addAll(0, Sets.fixedSize.of());
   Verify.assertSize(1, integers);
   Verify.assertStartsWith(integers, 5);
   FastList<String> zeroSizedList = FastList.newList(0);
   zeroSizedList.addAll(0, this.newWith("1", "2"));
 }
 @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);
 }
 @Override
 public void onError(final Throwable e) {
   // TODO throw if fatal ?;
   FastList list;
   synchronized (this) {
     if (terminated) {
       return;
     }
     if (emitting) {
       if (queue == null) {
         queue = new FastList();
       }
       queue.add(new ErrorSentinel(e));
       return;
     }
     emitting = true;
     list = queue;
     queue = null;
   }
   drainQueue(list);
   delegate.onError(e);
   synchronized (this) {
     emitting = false;
   }
 }
 @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());
 }
  @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 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 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 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);
 }
 @Override
 @Test
 public void forEach() {
   super.forEach();
   MutableList<Integer> list = FastList.newList();
   CompositeFastList<Integer> iterables = new CompositeFastList<Integer>();
   iterables.addComposited(Interval.oneTo(5).toList());
   iterables.addComposited(Interval.fromTo(6, 10).toList());
   iterables.forEach(CollectionAddProcedure.on(list));
   Verify.assertSize(10, list);
   Verify.assertAllSatisfy(list, Predicates.greaterThan(0).and(Predicates.lessThan(11)));
 }
 @Test
 public void addAllEmpty() {
   MutableList<Integer> integers = MultiReaderFastList.newList();
   integers.addAll(Lists.fixedSize.of());
   Verify.assertEmpty(integers);
   integers.addAll(Sets.fixedSize.of());
   Verify.assertEmpty(integers);
   integers.addAll(FastList.newList());
   Verify.assertEmpty(integers);
   integers.addAll(ArrayAdapter.newArray());
   Verify.assertEmpty(integers);
 }
  @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);
  }
 @Override
 @Test
 public void forEachWithIndex() {
   super.forEachWithIndex();
   MutableList<Integer> list = FastList.newList();
   CompositeFastList<Integer> iterables = new CompositeFastList<Integer>();
   iterables.addComposited(Interval.fromTo(6, 10).toList());
   iterables.addComposited(Interval.oneTo(5).toList());
   iterables.forEachWithIndex((each, index) -> list.add(index, each));
   Verify.assertSize(10, list);
   Verify.assertAllSatisfy(list, Predicates.greaterThan(0).and(Predicates.lessThan(11)));
   Verify.assertStartsWith(list, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5);
 }
 @Override
 @Test
 public void forEachWith() {
   super.forEachWith();
   MutableList<Integer> list = FastList.newList();
   CompositeFastList<Integer> iterables = new CompositeFastList<Integer>();
   iterables.addComposited(Interval.fromTo(6, 10).toList());
   iterables.addComposited(Interval.oneTo(5).toList());
   iterables.forEachWith((each, parameter) -> list.add(parameter.intValue(), each), 0);
   Verify.assertSize(10, list);
   Verify.assertAllSatisfy(list, Predicates.greaterThan(0).and(Predicates.lessThan(11)));
   Verify.assertStartsWith(list, 5, 4, 3, 2, 1, 10, 9, 8, 7, 6);
 }
  @Override
  @Test
  public void addAllIterable() {
    super.addAllIterable();

    MutableList<Integer> integers = MultiReaderFastList.newList();
    Assert.assertTrue(integers.addAllIterable(Lists.fixedSize.of(1, 2, 3, 4)));
    Verify.assertContainsAll(integers, 1, 2, 3, 4);
    Assert.assertTrue(integers.addAllIterable(FastList.<Integer>newList(4).with(1, 2, 3, 4)));
    Verify.assertStartsWith(integers, 1, 2, 3, 4, 1, 2, 3, 4);
    Assert.assertTrue(integers.addAllIterable(Sets.fixedSize.of(5)));
    Verify.assertStartsWith(integers, 1, 2, 3, 4, 1, 2, 3, 4, 5);
  }
 @Override
 @Test
 public void collectWith() {
   Function2<Integer, Integer, Integer> addZeroFunction = (each, parameter) -> each + parameter;
   Verify.assertContainsAll(
       MultiReaderFastList.newListWith(1, 2, 3).collectWith(addZeroFunction, 0), 1, 2, 3);
   Verify.assertContainsAll(
       MultiReaderFastList.newListWith(1, 2, 3)
           .collectWith(addZeroFunction, 0, FastList.newList()),
       1,
       2,
       3);
 }