import "copyrightAndOthers.stg"
import "primitiveEquals.stg"
import "primitiveHashCode.stg"
import "primitiveLiteral.stg"

isTest() ::= "true"

targetPath() ::= "org/eclipse/collections/impl/collection/mutable/primitive"

fileName(primitive) ::= "Abstract<primitive.name>IterableTestCase"

class(primitive) ::= <<
<body(primitive.type, primitive.wrapperName, primitive.name)>
>>

body(type, wrapperName, name) ::= <<
<copyrightAndOthers()>

package org.eclipse.collections.impl.collection.mutable.primitive;

import java.util.Arrays;
<if(primitive.floatingPoint)>import java.util.HashSet;<endif>
import java.util.List;
import java.util.NoSuchElementException;
<if(primitive.floatingPoint)>import java.util.Set;<endif>

import org.eclipse.collections.api.<name>Iterable;
import org.eclipse.collections.api.Lazy<name>Iterable;
import org.eclipse.collections.api.RichIterable;
import org.eclipse.collections.api.block.function.primitive.<name>ToObjectFunction;
import org.eclipse.collections.api.iterator.<name>Iterator;
import org.eclipse.collections.api.list.primitive.Mutable<name>List;
import org.eclipse.collections.impl.bag.mutable.primitive.<name>HashBag;
import org.eclipse.collections.impl.block.factory.primitive.<name>Predicates;
import org.eclipse.collections.impl.factory.Bags;
import org.eclipse.collections.impl.factory.Lists;
import org.eclipse.collections.impl.factory.Sets;
import org.eclipse.collections.impl.factory.primitive.BooleanLists;
import org.eclipse.collections.impl.factory.primitive.BooleanSets;
import org.eclipse.collections.impl.factory.primitive.ByteLists;
import org.eclipse.collections.impl.factory.primitive.ByteSets;
import org.eclipse.collections.impl.factory.primitive.CharLists;
import org.eclipse.collections.impl.factory.primitive.CharSets;
import org.eclipse.collections.impl.factory.primitive.DoubleLists;
import org.eclipse.collections.impl.factory.primitive.DoubleSets;
import org.eclipse.collections.impl.factory.primitive.FloatLists;
import org.eclipse.collections.impl.factory.primitive.FloatSets;
import org.eclipse.collections.impl.factory.primitive.IntLists;
import org.eclipse.collections.impl.factory.primitive.IntSets;
import org.eclipse.collections.impl.factory.primitive.LongLists;
import org.eclipse.collections.impl.factory.primitive.LongSets;
import org.eclipse.collections.impl.factory.primitive.ShortLists;
import org.eclipse.collections.impl.factory.primitive.ShortSets;
<if(primitive.floatingPoint)>import org.eclipse.collections.impl.list.Interval;<endif>
import org.eclipse.collections.impl.list.mutable.primitive.<name>ArrayList;
import org.eclipse.collections.impl.set.mutable.primitive.<name>HashSet;
import org.eclipse.collections.impl.test.Verify;
import org.junit.Assert;
import org.junit.Test;

/**
 * Abstract JUnit test for {@link <name>Iterable}s
 * This file was automatically generated from template file abstractPrimitiveIterableTestCase.stg.
 */
public abstract class Abstract<name>IterableTestCase
{
    protected abstract <name>Iterable classUnderTest();

    protected abstract <name>Iterable newWith(<type>... elements);

    protected abstract <name>Iterable newMutableCollectionWith(<type>... elements);

    protected abstract RichIterable\<<wrapperName>\> newObjectCollectionWith(<wrapperName>... elements);

    @Test
    public void newCollectionWith()
    {
        <name>Iterable iterable = this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">);
        Verify.assertSize(3, iterable);
        Verify.assertSize(4, this.newWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">));
        Assert.assertTrue(iterable.containsAll(<["1", "2", "3"]:(literal.(type))(); separator=", ">));

        <name>Iterable iterable1 = this.newWith();
        Verify.assertEmpty(iterable1);
        Assert.assertFalse(iterable1.containsAll(<["1", "2", "3"]:(literal.(type))(); separator=", ">));

        <name>Iterable iterable2 = this.newWith(<(literal.(type))("1")>);
        Verify.assertSize(1, iterable2);
        Assert.assertFalse(iterable2.containsAll(<["1", "2", "3"]:(literal.(type))(); separator=", ">));
    }

    @Test
    public void newCollection()
    {
        Assert.assertEquals(this.newMutableCollectionWith(), this.newWith());
        Assert.assertEquals(this.newMutableCollectionWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">));
        Assert.assertEquals(this.newMutableCollectionWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">), this.newWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">));
    }

    @Test
    public void isEmpty()
    {
        Verify.assertEmpty(this.newWith());
        Verify.assertNotEmpty(this.classUnderTest());
        Verify.assertNotEmpty(this.newWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">));
        Verify.assertNotEmpty(this.newWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">));
        Verify.assertNotEmpty(this.newWith(<["0", "31"]:(literal.(type))(); separator=", ">));
        Verify.assertNotEmpty(this.newWith(<["31", "32"]:(literal.(type))(); separator=", ">));
        Verify.assertNotEmpty(this.newWith(<["32", "33"]:(literal.(type))(); separator=", ">));
    }

    @Test
    public void notEmpty()
    {
        Assert.assertFalse(this.newWith().notEmpty());
        Assert.assertTrue(this.classUnderTest().notEmpty());
        Assert.assertTrue(this.newWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">).notEmpty());
        Assert.assertTrue(this.newWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">).notEmpty());
        Assert.assertTrue(this.newWith(<["0", "31"]:(literal.(type))(); separator=", ">).notEmpty());
        Assert.assertTrue(this.newWith(<["31", "32"]:(literal.(type))(); separator=", ">).notEmpty());
        Assert.assertTrue(this.newWith(<["32", "33"]:(literal.(type))(); separator=", ">).notEmpty());
    }

    @Test
    public void tap()
    {
        Mutable<name>List tapResult = <name>Lists.mutable.empty();
        <name>Iterable collection = this.newWith(<["14", "2", "30", "31", "32", "35", "0", "1"]:(literal.(type))(); separator=", ">);
        Assert.assertSame(collection, collection.tap(tapResult::add));
        Assert.assertEquals(collection.toList(), tapResult);
    }

    @Test
    public void contains()
    {
        <name>Iterable iterable = this.newWith(<["14", "2", "30", "31", "32", "35", "0", "1"]:(literal.(type))(); separator=", ">);
        Assert.assertFalse(iterable.contains(<(literal.(type))("29")>));
        Assert.assertFalse(iterable.contains(<(literal.(type))("49")>));

        <type>[] numbers = {<["14", "2", "30", "31", "32", "35", "0", "1"]:(literal.(type))(); separator=", ">};
        for (<type> number : numbers)
        {
            Assert.assertTrue(iterable.contains(number));
        }

        Assert.assertFalse(iterable.contains(<(literal.(type))("-1")>));
        Assert.assertFalse(iterable.contains(<(literal.(type))("29")>));
        Assert.assertFalse(iterable.contains(<(literal.(type))("49")>));

        <name>Iterable iterable1 = this.newWith(<["0", "1", "1", "2", "2", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(iterable1.contains(<(literal.(type))("0")>));
        Assert.assertTrue(iterable1.contains(<(literal.(type))("1")>));
        Assert.assertTrue(iterable1.contains(<(literal.(type))("2")>));
        Assert.assertFalse(iterable1.contains(<(literal.(type))("3")>));

        <name>Iterable iterable2 = this.classUnderTest();
        for (<type> each = 1; each \<= iterable2.size(); each++)
        {
            Assert.assertTrue(iterable2.contains(each));
        }
        Assert.assertFalse(iterable2.contains(<(castIntToNarrowTypeWithParens.(type))("iterable2.size() + 1")>));
    }

<if(primitive.floatingPoint)>
    <NaNTests("NaN")>
    <NaNTests("NEGATIVE_INFINITY")>
    <NaNTests("POSITIVE_INFINITY")>
    <ZeroTests()>
    <NaNEqualsTests()>
    <differentNaNs()>
<endif>
    @Test
    public void containsAllArray()
    {
        Assert.assertTrue(this.classUnderTest().containsAll(this.classUnderTest().toArray()));
        Assert.assertFalse(this.classUnderTest().containsAll(<(castIntToNarrowTypeWithParens.(type))("this.classUnderTest().size() + 1")>));

        <name>Iterable iterable = this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(iterable.containsAll(<(literal.(type))("1")>));
        Assert.assertTrue(iterable.containsAll(<["1", "2", "3"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(iterable.containsAll(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(iterable.containsAll(<["1", "2", "4"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(iterable.containsAll(<["4", "5", "6"]:(literal.(type))(); separator=", ">));

        <name>Iterable iterable1 = this.newWith(<["14", "2", "30", "32", "35", "0", "1"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(iterable1.containsAll(<(literal.(type))("14")>));
        Assert.assertTrue(iterable1.containsAll(<(literal.(type))("35")>));
        Assert.assertFalse(iterable1.containsAll(<(literal.(type))("-1")>));
        Assert.assertTrue(iterable1.containsAll(<["14", "1", "30"]:(literal.(type))(); separator=", ">));
        Assert.assertTrue(iterable1.containsAll(<["14", "1", "32"]:(literal.(type))(); separator=", ">));
        Assert.assertTrue(iterable1.containsAll(<["14", "1", "35"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(iterable1.containsAll(<["0", "2", "35", "-1"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(iterable1.containsAll(<["31", "-1"]:(literal.(type))(); separator=", ">));

        <name>Iterable iterable2 = this.newWith(<["0", "1", "1", "2", "2", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(iterable2.containsAll(<(literal.(type))("0")>));
        Assert.assertTrue(iterable2.containsAll(<["0", "0", "0"]:(literal.(type))(); separator=", ">));
        Assert.assertTrue(iterable2.containsAll(<["0", "1", "1"]:(literal.(type))(); separator=", ">));
        Assert.assertTrue(iterable2.containsAll(<["0", "1", "2"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(iterable2.containsAll(<["0", "1", "2", "3", "4"]:(literal.(type))(); separator=", ">));
        Assert.assertFalse(iterable2.containsAll(<["3", "4"]:(literal.(type))(); separator=", ">));
    }

    @Test
    public void containsAllIterable()
    {
        <name>Iterable source = this.classUnderTest();
        Assert.assertTrue(source.containsAll(this.classUnderTest()));
        Assert.assertFalse(source.containsAll(<name>ArrayList.newListWith(<(castIntToNarrowTypeWithParens.(type))("source.size() + 1")>)));

        <name>Iterable iterable = this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(this.newWith().containsAll(new <name>ArrayList()));
        Assert.assertFalse(this.newWith().containsAll(<name>ArrayList.newListWith(<(literal.(type))("1")>)));
        Assert.assertTrue(iterable.containsAll(<name>ArrayList.newListWith(<(literal.(type))("1")>)));
        Assert.assertTrue(iterable.containsAll(<name>ArrayList.newListWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(iterable.containsAll(<name>ArrayList.newListWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(iterable.containsAll(<name>ArrayList.newListWith(<["1", "2", "4"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(iterable.containsAll(<name>ArrayList.newListWith(<["4", "5", "6"]:(literal.(type))(); separator=", ">)));

        <name>Iterable iterable1 = this.newWith(<["14", "2", "30", "32", "35", "0", "1"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(iterable1.containsAll(<name>HashSet.newSetWith(<(literal.(type))("14")>)));
        Assert.assertTrue(iterable1.containsAll(<name>HashSet.newSetWith(<(literal.(type))("35")>)));
        Assert.assertFalse(iterable1.containsAll(<name>HashSet.newSetWith(<(literal.(type))("-1")>)));
        Assert.assertTrue(iterable1.containsAll(<name>HashSet.newSetWith(<["14", "1", "30"]:(literal.(type))(); separator=", ">)));
        Assert.assertTrue(iterable1.containsAll(<name>HashSet.newSetWith(<["14", "1", "32"]:(literal.(type))(); separator=", ">)));
        Assert.assertTrue(iterable1.containsAll(<name>HashSet.newSetWith(<["14", "1", "35"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(iterable1.containsAll(<name>HashSet.newSetWith(<["0", "2", "35", "-1"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(iterable1.containsAll(<name>HashSet.newSetWith(<["31", "-1"]:(literal.(type))(); separator=", ">)));

        <name>Iterable iterable2 = this.newWith(<["0", "1", "1", "2", "2", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(iterable2.containsAll(<name>ArrayList.newListWith(<(literal.(type))("0")>)));
        Assert.assertTrue(iterable2.containsAll(<name>ArrayList.newListWith(<["0", "0", "0"]:(literal.(type))(); separator=", ">)));
        Assert.assertTrue(iterable2.containsAll(<name>ArrayList.newListWith(<["0", "1", "1"]:(literal.(type))(); separator=", ">)));
        Assert.assertTrue(iterable2.containsAll(<name>ArrayList.newListWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(iterable2.containsAll(<name>ArrayList.newListWith(<["0", "1", "2", "3", "4"]:(literal.(type))(); separator=", ">)));
        Assert.assertFalse(iterable2.containsAll(<name>ArrayList.newListWith(<["3", "4"]:(literal.(type))(); separator=", ">)));
    }

    @Test
    public abstract void <type>Iterator();

    @Test(expected = NoSuchElementException.class)
    public void <type>Iterator_throws()
    {
        <name>Iterator iterator = this.classUnderTest().<type>Iterator();
        while (iterator.hasNext())
        {
            iterator.next();
        }
        iterator.next();
    }

    @Test(expected = NoSuchElementException.class)
    public void <type>Iterator_throws_non_empty_collection()
    {
        <name>Iterable iterable = this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">);
        <name>Iterator iterator = iterable.<type>Iterator();
        while (iterator.hasNext())
        {
            iterator.next();
        }
        iterator.next();
    }

    @Test
    public void forEach()
    {
        <wideType.(type)>[] sum = new <wideType.(type)>[1];
        this.classUnderTest().forEach(each -> sum[0] += each);

        int size = this.classUnderTest().size();
        long sum1 = (long) ((size * (size + 1)) / 2);
        Assert.assertEquals(sum1, sum[0]<wideDelta.(type)>);
    }

    @Test
    public void size()
    {
        Verify.assertSize(0, this.newWith());
        Verify.assertSize(1, this.newWith(<(literal.(type))("3")>));
        Verify.assertSize(3, this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">));
    }

    @Test
    public void count()
    {
        <name>Iterable iterable = this.classUnderTest();
        int size = iterable.size();
        Assert.assertEquals(size >= 3 ? 3 : size, iterable.count(<name>Predicates.lessThan(<(literal.(type))("4")>)));
        Assert.assertEquals(2L, this.newWith(<["1", "0", "2"]:(literal.(type))(); separator=", ">).count(<name>Predicates.greaterThan(<zero.(type)>)));

        Assert.assertEquals(1, this.newWith(<["1"]:(literal.(type))(); separator=", ">).count(<name>Predicates.alwaysTrue()));
        Assert.assertEquals(0, this.newWith(<["1"]:(literal.(type))(); separator=", ">).count(<name>Predicates.alwaysFalse()));
    }

    @Test
    public void anySatisfy()
    {
        Assert.assertTrue(this.newWith(<["1", "-1", "2"]:(literal.(type))(); separator=", ">).anySatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["1", "-1", "2"]:(literal.(type))(); separator=", ">).anySatisfy(<name>Predicates.equal(<(literal.(type))("0")>)));
        Assert.assertTrue(this.newWith(<["-1", "-1", "-2", "31", "32"]:(literal.(type))(); separator=", ">).anySatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertTrue(this.newWith(<["2", "-1", "-2", "31", "32"]:(literal.(type))(); separator=", ">).anySatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["1", "-1", "31", "32"]:(literal.(type))(); separator=", ">).anySatisfy(<name>Predicates.equal(<(literal.(type))("0")>)));
        Assert.assertTrue(this.newWith(<["32"]:(literal.(type))(); separator=", ">).anySatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        <name>Iterable iterable = this.newWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(iterable.anySatisfy(value -> <(lessThan.(type))("value", {<(literal.(type))("3")>})>));
        Assert.assertFalse(iterable.anySatisfy(<name>Predicates.greaterThan(<(literal.(type))("3")>)));

        <name>Iterable iterable1 = this.classUnderTest();
        int size = iterable1.size();
        Assert.assertEquals(size > 3, iterable1.anySatisfy(<name>Predicates.greaterThan(<(literal.(type))("3")>)));
        Assert.assertEquals(size != 0, iterable1.anySatisfy(<name>Predicates.lessThan(<(literal.(type))("3")>)));
    }

    @Test
    public void allSatisfy()
    {
        Assert.assertFalse(this.newWith(<["1", "0", "2"]:(literal.(type))(); separator=", ">).allSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertTrue(this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).allSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["1", "0", "31", "32"]:(literal.(type))(); separator=", ">).allSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["1", "0", "31", "32"]:(literal.(type))(); separator=", ">).allSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertTrue(this.newWith(<["1", "2", "31", "32"]:(literal.(type))(); separator=", ">).allSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["32"]:(literal.(type))(); separator=", ">).allSatisfy(<name>Predicates.equal(<(literal.(type))("33")>)));
        Assert.assertFalse(this.newWith(<["-32"]:(literal.(type))(); separator=", ">).allSatisfy(<name>Predicates.equal(<(literal.(type))("33")>)));
        <name>Iterable iterable = this.newWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertFalse(iterable.allSatisfy(value -> <(lessThan.(type))({<(literal.(type))("3")>}, "value")>));
        Assert.assertTrue(iterable.allSatisfy(<name>Predicates.lessThan(<(literal.(type))("3")>)));

        <name>Iterable iterable1 = this.classUnderTest();
        int size = iterable1.size();
        Assert.assertEquals(size == 0, iterable1.allSatisfy(<name>Predicates.greaterThan(<(literal.(type))("3")>)));
        Assert.assertEquals(size \< 3, iterable1.allSatisfy(<name>Predicates.lessThan(<(literal.(type))("3")>)));
    }

    @Test
    public void noneSatisfy()
    {
        Assert.assertFalse(this.newWith(<["1", "0", "2"]:(literal.(type))(); separator=", ">).noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["1", "0", "2"]:(literal.(type))(); separator=", ">).noneSatisfy(<name>Predicates.equal(<(literal.(type))("0")>)));
        Assert.assertTrue(this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("3")>)));
        Assert.assertFalse(this.newWith(<["1", "0", "31", "32"]:(literal.(type))(); separator=", ">).noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["1", "0", "31", "32"]:(literal.(type))(); separator=", ">).noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        Assert.assertTrue(this.newWith(<["1", "2", "31", "32"]:(literal.(type))(); separator=", ">).noneSatisfy(<name>Predicates.lessThan(<(literal.(type))("0")>)));
        Assert.assertFalse(this.newWith(<["32"]:(literal.(type))(); separator=", ">).noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("0")>)));
        <name>Iterable iterable = this.newWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertFalse(iterable.noneSatisfy(value -> <(lessThan.(type))({<(literal.(type))("1")>}, "value")>));
        Assert.assertTrue(iterable.noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("3")>)));

        <name>Iterable iterable1 = this.classUnderTest();
        int size = iterable1.size();
        Assert.assertEquals(size \<= 3, iterable1.noneSatisfy(<name>Predicates.greaterThan(<(literal.(type))("3")>)));
        Assert.assertEquals(size == 0, iterable1.noneSatisfy(<name>Predicates.lessThan(<(literal.(type))("3")>)));
    }

    @Test
    public void collect()
    {
        <name>ToObjectFunction\<<wrapperName>\> function = parameter -> <(castIntToNarrowTypeWithParens.(type))("parameter - 1")>;
        Assert.assertEquals(this.newObjectCollectionWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).collect(function));
        <name>Iterable iterable = this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(this.newObjectCollectionWith(<["0", "1", "1", "2", "2", "2"]:(literal.(type))(); separator=", ">), iterable.collect(function));
        Assert.assertEquals(this.newObjectCollectionWith(), this.newWith().collect(function));
        Assert.assertEquals(this.newObjectCollectionWith(<(literal.(type))("2")>), this.newWith(<(literal.(type))("3")>).collect(function));
    }

    @Test
    public void collectWithTarget()
    {
        <name>ToObjectFunction\<<wrapperName>\> function = parameter -> <(castIntToNarrowTypeWithParens.(type))("parameter - 1")>;
        Assert.assertEquals(Bags.mutable.with(<["0", "1", "2"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).collect(function, Bags.mutable.empty()));
        <name>Iterable iterable = this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(Sets.mutable.with(<["0", "1", "2"]:(literal.(type))(); separator=", ">), iterable.collect(function, Sets.mutable.empty()));
        Assert.assertEquals(Lists.mutable.empty(), this.newWith().collect(function, Lists.mutable.empty()));
        Assert.assertEquals(Lists.mutable.with(<(literal.(type))("2")>), this.newWith(<(literal.(type))("3")>).collect(function, Lists.mutable.empty()));
    }

    @Test
    public void flatCollectWithTarget()
    {
        <name>ToObjectFunction\<List\<<wrapperName>\>> function = parameter -> Lists.mutable.with(<(castIntToNarrowTypeWithParens.(type))("parameter - 1")>);
        Assert.assertEquals(Bags.mutable.with(<["0", "1", "2"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).flatCollect(function, Bags.mutable.empty()));
        <name>Iterable iterable = this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(Sets.mutable.with(<["0", "1", "2"]:(literal.(type))(); separator=", ">), iterable.flatCollect(function, Sets.mutable.empty()));
        Assert.assertEquals(Lists.mutable.empty(), this.newWith().flatCollect(function, Lists.mutable.empty()));
        Assert.assertEquals(Lists.mutable.with(<(literal.(type))("2")>), this.newWith(<(literal.(type))("3")>).flatCollect(function, Lists.mutable.empty()));
    }

    @Test
    public void flatCollectIterableWithTarget()
    {
        <name>ToObjectFunction\<Iterable\<<wrapperName>\>> function = parameter -> Lists.mutable.with(<(castIntToNarrowTypeWithParens.(type))("parameter - 1")>).asLazy();
        Assert.assertEquals(Bags.mutable.with(<["0", "1", "2"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).flatCollect(function, Bags.mutable.empty()));
        <name>Iterable iterable = this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(Sets.mutable.with(<["0", "1", "2"]:(literal.(type))(); separator=", ">), iterable.flatCollect(function, Sets.mutable.empty()));
        Assert.assertEquals(Lists.mutable.empty(), this.newWith().flatCollect(function, Lists.mutable.empty()));
        Assert.assertEquals(Lists.mutable.with(<(literal.(type))("2")>), this.newWith(<(literal.(type))("3")>).flatCollect(function, Lists.mutable.empty()));
    }

    @Test
    public void collectPrimitivesToLists()
    {
        <name>Iterable iterable = this.newWith(<["1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(
                BooleanLists.mutable.with(true, true),
                iterable.collectBoolean(each -> true, BooleanLists.mutable.empty()));
        Assert.assertEquals(
                ByteLists.mutable.with((byte) 1, (byte) 1),
                iterable.collectByte(each -> (byte) 1, ByteLists.mutable.empty()));
        Assert.assertEquals(
                CharLists.mutable.with('a', 'a'),
                iterable.collectChar(each -> 'a', CharLists.mutable.empty()));
        Assert.assertEquals(
                ShortLists.mutable.with((short) 1, (short) 1),
                iterable.collectShort(each -> (short) 1, ShortLists.mutable.empty()));
        Assert.assertEquals(
                IntLists.mutable.with(1, 1),
                iterable.collectInt(each -> 1, IntLists.mutable.empty()));
        Assert.assertEquals(
                FloatLists.mutable.with(1.0f, 1.0f),
                iterable.collectFloat(each -> 1.0f, FloatLists.mutable.empty()));
        Assert.assertEquals(
                LongLists.mutable.with(1L, 1L),
                iterable.collectLong(each -> 1L, LongLists.mutable.empty()));
        Assert.assertEquals(
                DoubleLists.mutable.with(1.0d, 1.0d),
                iterable.collectDouble(each -> 1.0d, DoubleLists.mutable.empty()));
    }

    @Test
    public void collectPrimitivesToSets()
    {
        <name>Iterable iterable = this.newWith(<["1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(
                BooleanSets.mutable.with(false),
                iterable.collectBoolean(each -> false, BooleanSets.mutable.empty()));
        Assert.assertEquals(
                ByteSets.mutable.with((byte) 2),
                iterable.collectByte(each -> (byte) 2, ByteSets.mutable.empty()));
        Assert.assertEquals(
                CharSets.mutable.with('b'),
                iterable.collectChar(each -> 'b', CharSets.mutable.empty()));
        Assert.assertEquals(
                ShortSets.mutable.with((short) 2),
                iterable.collectShort(each -> (short) 2, ShortSets.mutable.empty()));
        Assert.assertEquals(
                IntSets.mutable.with(2),
                iterable.collectInt(each -> 2, IntSets.mutable.empty()));
        Assert.assertEquals(
                FloatSets.mutable.with(2.0f),
                iterable.collectFloat(each -> 2.0f, FloatSets.mutable.empty()));
        Assert.assertEquals(
                LongSets.mutable.with(2L),
                iterable.collectLong(each -> 2L, LongSets.mutable.empty()));
        Assert.assertEquals(
                DoubleSets.mutable.with(2.0d),
                iterable.collectDouble(each -> 2.0d, DoubleSets.mutable.empty()));
    }

    @Test
    public void select()
    {
        <name>Iterable iterable = this.classUnderTest();
        int size = iterable.size();
        Verify.assertSize(size >= 3 ? 3 : size, iterable.select(<name>Predicates.lessThan(<(literal.(type))("4")>)));
        Verify.assertSize(size >= 2 ? 2 : size, iterable.select(<name>Predicates.lessThan(<(literal.(type))("3")>)));
        <name>Iterable iterable1 = this.newWith(<["0", "1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(this.newMutableCollectionWith(<["0", "1"]:(literal.(type))(); separator=", ">), iterable1.select(<name>Predicates.lessThan(<(literal.(type))("2")>)));
        Assert.assertEquals(this.newMutableCollectionWith(<["2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">), iterable1.select(<name>Predicates.greaterThan(<(literal.(type))("1")>)));

        <name>Iterable iterable2 = this.newWith(<["0"]:(literal.(type))(); separator=", ">);
        Verify.assertSize(iterable2.size() == 1 ? 1 : 0, iterable2.select(<name>Predicates.alwaysTrue()));
        Verify.assertSize(0, iterable2.select(<name>Predicates.alwaysFalse()));
    }

    @Test
    public void selectWithTarget()
    {
        <name>Iterable iterable = this.classUnderTest();
        int size = iterable.size();
        Verify.assertSize(size >= 3 ? 3 : size, iterable.select(<name>Predicates.lessThan(<(literal.(type))("4")>), <name>Sets.mutable.empty()));
        Verify.assertSize(size >= 2 ? 2 : size, iterable.select(<name>Predicates.lessThan(<(literal.(type))("3")>), <name>Sets.mutable.empty()));
        <name>Iterable iterable1 = this.newWith(<["0", "1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(<name>Sets.mutable.with(<["0", "1"]:(literal.(type))(); separator=", ">), iterable1.select(<name>Predicates.lessThan(<(literal.(type))("2")>), <name>Sets.mutable.empty()));
        Assert.assertEquals(<name>Sets.mutable.with(<["2", "3"]:(literal.(type))(); separator=", ">), iterable1.select(<name>Predicates.greaterThan(<(literal.(type))("1")>), <name>Sets.mutable.empty()));
    }

    @Test
    public void reject()
    {
        <name>Iterable iterable = this.classUnderTest();
        int size = iterable.size();
        Verify.assertSize(size \<= 3 ? 0 : size - 3, iterable.reject(<name>Predicates.lessThan(<(literal.(type))("4")>)));
        Verify.assertSize(size \<= 2 ? 0 : size - 2, iterable.reject(<name>Predicates.lessThan(<(literal.(type))("3")>)));
        <name>Iterable iterable1 = this.newWith(<["0", "1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(this.newMutableCollectionWith(<["2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">), iterable1.reject(<name>Predicates.lessThan(<(literal.(type))("2")>)));
        Assert.assertEquals(this.newMutableCollectionWith(<["0", "1"]:(literal.(type))(); separator=", ">), iterable1.reject(<name>Predicates.greaterThan(<(literal.(type))("1")>)));

        <name>Iterable iterable2 = this.newWith(<["0"]:(literal.(type))(); separator=", ">);
        Verify.assertSize(iterable2.size() == 1 ? 1 : 0, iterable2.reject(<name>Predicates.alwaysFalse()));
        Verify.assertSize(0, iterable2.reject(<name>Predicates.alwaysTrue()));
    }

    @Test
    public void rejectWithTarget()
    {
        <name>Iterable iterable = this.classUnderTest();
        int size = iterable.size();
        Verify.assertSize(size \<= 3 ? 0 : size - 3, iterable.reject(<name>Predicates.lessThan(<(literal.(type))("4")>), <name>Sets.mutable.empty()));
        Verify.assertSize(size \<= 2 ? 0 : size - 2, iterable.reject(<name>Predicates.lessThan(<(literal.(type))("3")>), <name>Sets.mutable.empty()));
        <name>Iterable iterable1 = this.newWith(<["0", "1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(<name>Sets.mutable.with(<["2", "3"]:(literal.(type))(); separator=", ">), iterable1.reject(<name>Predicates.lessThan(<(literal.(type))("2")>), <name>Sets.mutable.empty()));
        Assert.assertEquals(<name>Sets.mutable.with(<["0", "1"]:(literal.(type))(); separator=", ">), iterable1.reject(<name>Predicates.greaterThan(<(literal.(type))("1")>), <name>Sets.mutable.empty()));
    }

    @Test
    public void detectIfNone()
    {
        <name>Iterable iterable = this.classUnderTest();
        int size = iterable.size();
        Assert.assertEquals(size >= 4 ? <(wideLiteral.(type))("4")> : <(wideLiteral.(type))("0")>, iterable.detectIfNone(<name>Predicates.equal(<(literal.(type))("4")>), <(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(size >= 2 ? <(wideLiteral.(type))("2")> : <(wideLiteral.(type))("0")>, iterable.detectIfNone(<name>Predicates.equal(<(literal.(type))("2")>), <(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(size > 0 ? <(wideLiteral.(type))("1")> : <(wideLiteral.(type))("0")>, iterable.detectIfNone(<name>Predicates.lessThan(<(literal.(type))("2")>), <(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(size > 3 ? <(wideLiteral.(type))("4")> : <(wideLiteral.(type))("0")>, iterable.detectIfNone(<name>Predicates.greaterThan(<(literal.(type))("3")>), <(literal.(type))("0")>)<(wideDelta.(type))>);

        <name>Iterable iterable1 = this.newWith(<["0", "1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(<(wideLiteral.(type))("0")>, iterable1.detectIfNone(<name>Predicates.lessThan(<(literal.(type))("1")>), <(literal.(type))("4")>)<(delta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("3")>, iterable1.detectIfNone(<name>Predicates.greaterThan(<(literal.(type))("2")>), <(literal.(type))("4")>)<(delta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("4")>, iterable1.detectIfNone(<name>Predicates.greaterThan(<(literal.(type))("4")>), <(literal.(type))("4")>)<(delta.(type))>);
    }

    @Test
    public void max()
    {
        <(maxTests.(type))(type, name)>
    }

    @Test(expected = NoSuchElementException.class)
    public void max_throws_emptyCollection()
    {
        this.newWith().max();
    }

    @Test
    public void min()
    {
        <(minTests.(type))(type, name)>
    }

    @Test(expected = NoSuchElementException.class)
    public void min_throws_emptyCollection()
    {
        this.newWith().min();
    }

    @Test
    public void minIfEmpty()
    {
        Assert.assertEquals(<(wideLiteral.(type))("5")>, this.newWith().minIfEmpty(<(literal.(type))("5")>)<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("0")>, this.newWith().minIfEmpty(<(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("0")>, this.newWith(<["1", "0", "9", "7"]:(literal.(type))(); separator=", ">).minIfEmpty(<(literal.(type))("5")>)<(wideDelta.(type))>);
        int size = this.classUnderTest().size();
        Assert.assertEquals(size == 0 ? <(literal.(type))("5")> : <(literal.(type))("1")>, this.classUnderTest().minIfEmpty(<(literal.(type))("5")>)<(wideDelta.(type))>);
    }

    @Test
    public void maxIfEmpty()
    {
        Assert.assertEquals(<(wideLiteral.(type))("5")>, this.newWith().maxIfEmpty(<(literal.(type))("5")>)<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("0")>, this.newWith().maxIfEmpty(<(literal.(type))("0")>)<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("9")>, this.newWith(<["1", "0", "9", "7"]:(literal.(type))(); separator=", ">).maxIfEmpty(<(literal.(type))("5")>)<(wideDelta.(type))>);
        int size = this.classUnderTest().size();
        Assert.assertEquals(size == 0 ? <(literal.(type))("5")> : size, this.classUnderTest().maxIfEmpty(<(literal.(type))("5")>)<(wideDelta.(type))>);
    }

    @Test
    public void sum()
    {
        int size = this.classUnderTest().size();
        long sum = (long) ((size * (size + 1)) / 2);
        Assert.assertEquals(sum, this.classUnderTest().sum()<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("10")>, this.newWith(<["0", "1", "2", "3", "4"]:(literal.(type))(); separator=", ">).sum()<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("93")>, this.newWith(<["30", "31", "32"]:(literal.(type))(); separator=", ">).sum()<wideDelta.(type)>);
    }

    @Test
    public void summaryStatistics()
    {
        int size = this.classUnderTest().size();
        long sum = (long) ((size * (size + 1)) / 2);
        Assert.assertEquals(sum, this.classUnderTest().summaryStatistics().getSum()<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("10")>, this.newWith(<["0", "1", "2", "3", "4"]:(literal.(type))(); separator=", ">).summaryStatistics().getSum()<(wideDelta.(type))>);
        Assert.assertEquals(<(wideLiteral.(type))("93")>, this.newWith(<["30", "31", "32"]:(literal.(type))(); separator=", ">).summaryStatistics().getSum()<wideDelta.(type)>);
    }

    <if(primitive.floatPrimitive)>@Test
public void sumConsistentRounding()
{
    <name>Iterable iterable = this.newWith(Interval.oneTo(100_000)
            .toList()
            .shuffleThis()
            .collect<name>(i -> 1.0f / (i.floatValue() * i.floatValue() * i.floatValue() * i.floatValue()))
            .toArray());

    // The test only ensures the consistency/stability of rounding. This is not meant to test the "correctness" of the float calculation result.
    // Indeed the lower bits of this calculation result are always incorrect due to the information loss of original float values.
    Assert.assertEquals(
            1.082323233761663,
            iterable.sum(),
            1.0e-15);
}

    <elseif(primitive.doublePrimitive)>@Test
public void sumConsistentRounding()
{
    <name>Iterable iterable = this.newWith(Interval.oneTo(100_000)
            .toList()
            .shuffleThis()
            .collect<name>(i -> <["1.0"]:(decimalLiteral.(type))()> / (i.<type>Value() * i.<type>Value() * i.<type>Value() * i.<type>Value()))
            .toArray());

    Assert.assertEquals(
            1.082323233711138,
            iterable.sum(),
            1.0e-15);
}

    <endif>
    @Test
    public void average()
    {
        int size = this.classUnderTest().size();
        long sum = (long) ((size * (size + 1)) / 2);
        double average = sum / size;
        Assert.assertEquals(average, this.classUnderTest().average(), 0.0);
        Assert.assertEquals(2.5, this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">).average(), 0.0);
        Assert.assertEquals(2.5, this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">).average(), 0.0);
        Assert.assertEquals(31.0, this.newWith(<["30", "30", "31", "31", "32", "32"]:(literal.(type))(); separator=", ">).average(), 0.0);
    }

    @Test(expected = ArithmeticException.class)
    public void averageThrowsOnEmpty()
    {
        this.newWith().average();
    }

    /**
     * @since 9.0
     */
    @Test
    public void averageIfEmpty()
    {
        Assert.assertEquals(2.5, this.newWith().averageIfEmpty(2.5), 0.0);
        int size = this.classUnderTest().size();
        long sum = (long) ((size * (size + 1)) / 2);
        double average = sum / size;
        Assert.assertEquals(average, this.classUnderTest().averageIfEmpty(0.0), 0.0);
        Assert.assertEquals(2.5, this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">).averageIfEmpty(0.0), 0.0);
        Assert.assertEquals(2.5, this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">).averageIfEmpty(0.0), 0.0);
        Assert.assertEquals(31.0, this.newWith(<["30", "30", "31", "31", "32", "32"]:(literal.(type))(); separator=", ">).averageIfEmpty(0.0), 0.0);
    }

    @Test
    public void median()
    {
        Assert.assertEquals(1.0, this.newWith(<["1"]:(literal.(type))(); separator=", ">).median(), 0.0);
        Assert.assertEquals(2.5, this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">).median(), 0.0);
        Assert.assertEquals(3.0, this.newWith(<["1", "2", "3", "4", "5"]:(literal.(type))(); separator=", ">).median(), 0.0);
        Assert.assertEquals(31.0, this.newWith(<["30", "30", "31", "31", "32"]:(literal.(type))(); separator=", ">).median(), 0.0);
        Assert.assertEquals(30.5, this.newWith(<["1", "30", "30", "31", "31", "32"]:(literal.(type))(); separator=", ">).median(), 0.0);
    }

    @Test(expected = ArithmeticException.class)
    public void medianThrowsOnEmpty()
    {
        this.newWith().median();
    }

    /**
     * @since 9.0
     */
    @Test
    public void medianIfEmpty()
    {
        Assert.assertEquals(2.5, this.newWith().medianIfEmpty(2.5), 0.0);
        Assert.assertEquals(1.0, this.newWith(<["1"]:(literal.(type))(); separator=", ">).medianIfEmpty(0.0), 0.0);
        Assert.assertEquals(2.5, this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">).medianIfEmpty(0.0), 0.0);
        Assert.assertEquals(3.0, this.newWith(<["1", "2", "3", "4", "5"]:(literal.(type))(); separator=", ">).medianIfEmpty(0.0), 0.0);
        Assert.assertEquals(31.0, this.newWith(<["30", "30", "31", "31", "32"]:(literal.(type))(); separator=", ">).medianIfEmpty(0.0), 0.0);
        Assert.assertEquals(30.5, this.newWith(<["1", "30", "30", "31", "31", "32"]:(literal.(type))(); separator=", ">).medianIfEmpty(0.0), 0.0);
    }

    @Test
    public void toArray()
    {
        Assert.assertEquals(this.classUnderTest().size(), this.classUnderTest().toArray().length);
        <name>Iterable iterable = this.newWith(<["1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(Arrays.equals(new <type>[]{<["1", "2"]:(literal.(type))(); separator=", ">}, iterable.toArray())
                || Arrays.equals(new <type>[]{<["2", "1"]:(literal.(type))(); separator=", ">}, iterable.toArray()));
        Assert.assertTrue(Arrays.equals(new <type>[]{<["0", "1"]:(literal.(type))(); separator=", ">}, this.newWith(<["0", "1"]:(literal.(type))(); separator=", ">).toArray())
                || Arrays.equals(new <type>[]{<["1", "0"]:(literal.(type))(); separator=", ">}, this.newWith(<["0", "1"]:(literal.(type))(); separator=", ">).toArray()));
        Assert.assertTrue(Arrays.equals(new <type>[]{<["1", "31"]:(literal.(type))(); separator=", ">}, this.newWith(<["1", "31"]:(literal.(type))(); separator=", ">).toArray())
                || Arrays.equals(new <type>[]{<["31", "1"]:(literal.(type))(); separator=", ">}, this.newWith(<["1", "31"]:(literal.(type))(); separator=", ">).toArray()));
        Assert.assertTrue(Arrays.equals(new <type>[]{<["31", "35"]:(literal.(type))(); separator=", ">}, this.newWith(<["31", "35"]:(literal.(type))(); separator=", ">).toArray())
                || Arrays.equals(new <type>[]{<["35", "31"]:(literal.(type))(); separator=", ">}, this.newWith(<["31", "35"]:(literal.(type))(); separator=", ">).toArray()));
        Assert.assertArrayEquals(new <type>[]{}, this.newWith().toArray()<(delta.(type))>);
        Assert.assertArrayEquals(new <type>[]{<(literal.(type))("32")>}, this.newWith(<(literal.(type))("32")>).toArray()<(delta.(type))>);
    }

    @Test
    public void toArrayWithTargetArray()
    {
        <type>[] originalAsSortedArray = this.classUnderTest().toSortedArray();

        <type>[] target = new <type>[this.classUnderTest().size()];

        Assert.assertSame(target, this.classUnderTest().toArray(target));
        Arrays.sort(target);
        Assert.assertTrue(Arrays.equals(originalAsSortedArray, target));

        if (this.classUnderTest().size() > 0)
        {
            <type>[] targetTooSmall = new <type>[this.classUnderTest().size() - 1];
            <type>[] result = this.classUnderTest().toArray(targetTooSmall);
            Assert.assertNotSame(targetTooSmall, result);
            Arrays.sort(result);
            Assert.assertTrue(Arrays.equals(this.classUnderTest().toSortedArray(), result));
        }

        <type>[] targetTooBig = new <type>[this.classUnderTest().size() + 1];
        <type>[] bigResult = this.classUnderTest().toArray(targetTooBig);
        Assert.assertSame(targetTooBig, bigResult);
        Arrays.sort(targetTooBig);
        for (int i = 0; i \< originalAsSortedArray.length; i++)
        {
            Assert.assertEquals(originalAsSortedArray[i], bigResult[i + 1]<(delta.(type))>);
        }
    }

    @Test
    public void toSortedArray()
    {
        <name>Iterable iterable = this.classUnderTest();
        int size = iterable.size();
        <type>[] array = new <type>[size];
        for (int i = 0; i \< size; i++)
        {
            array[i] = <(castIntToNarrowTypeWithParens.(type))("i + 1")>;
        }

        Assert.assertArrayEquals(array, iterable.toSortedArray()<(delta.(type))>);
        Assert.assertArrayEquals(new <type>[]{<["1", "3", "7", "9"]:(literal.(type))(); separator=", ">},
                this.newWith(<["3", "1", "9", "7"]:(literal.(type))(); separator=", ">).toSortedArray()<(delta.(type))>);
    }

    @Test
    public void testEquals()
    {
        <name>Iterable iterable1 = this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable2 = this.newWith(<["1", "2", "3", "4"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable3 = this.newWith(<["5", "6", "7", "8"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable4 = this.newWith(<["5", "6", "7"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable5 = this.newWith(<["0", "1", "1", "2", "2", "2"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable6 = this.newWith(<["1", "31", "32"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable7 = this.newWith(<["35", "31", "1"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable8 = this.newWith(<["32", "31", "1", "50"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable9 = this.newWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable10 = this.newWith(<["0", "1", "3"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable11 = this.newWith(<["3", "1", "2"]:(literal.(type))(); separator=", ">);
        <name>Iterable iterable12 = this.newWith(<["3"]:(literal.(type))(); separator=", ">);

        Verify.assertEqualsAndHashCode(iterable1, iterable2);
        Verify.assertPostSerializedEqualsAndHashCode(iterable1);
        Verify.assertPostSerializedEqualsAndHashCode(iterable12);
        Verify.assertPostSerializedEqualsAndHashCode(iterable5);
        Verify.assertPostSerializedEqualsAndHashCode(iterable6);
        Assert.assertNotEquals(iterable12, iterable11);
        Assert.assertNotEquals(iterable1, iterable3);
        Assert.assertNotEquals(iterable1, iterable4);
        Assert.assertNotEquals(iterable6, iterable7);
        Assert.assertNotEquals(iterable6, iterable8);
        Assert.assertNotEquals(iterable9, iterable10);
        Assert.assertNotEquals(iterable9, iterable11);
        Assert.assertNotEquals(this.newWith(), this.newWith(<(literal.(type))("100")>));
    }

    @Test
    public void testHashCode()
    {
        Assert.assertEquals(this.newObjectCollectionWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).hashCode(), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).hashCode());
        Assert.assertEquals(this.newObjectCollectionWith(<["0", "1", "31"]:(literal.(type))(); separator=", ">).hashCode(), this.newWith(<["0", "1", "31"]:(literal.(type))(); separator=", ">).hashCode());
        Assert.assertEquals(this.newObjectCollectionWith(<["32"]:(literal.(type))(); separator=", ">).hashCode(), this.newWith(<["32"]:(literal.(type))(); separator=", ">).hashCode());
        Assert.assertNotEquals(this.newObjectCollectionWith(<["32"]:(literal.(type))(); separator=", ">).hashCode(), this.newWith(<["0"]:(literal.(type))(); separator=", ">).hashCode());
        Assert.assertEquals(this.newObjectCollectionWith(<["31", "32", "50"]:(literal.(type))(); separator=", ">).hashCode(), this.newWith(<["31", "32", "50"]:(literal.(type))(); separator=", ">).hashCode());
        Assert.assertEquals(this.newObjectCollectionWith(<["32", "50", "60"]:(literal.(type))(); separator=", ">).hashCode(), this.newWith(<["32", "50", "60"]:(literal.(type))(); separator=", ">).hashCode());
        Assert.assertEquals(this.newObjectCollectionWith().hashCode(), this.newWith().hashCode());
    }

    @Test
    public void testToString()
    {
        Assert.assertEquals("[]", this.newWith().toString());
        Assert.assertEquals("[<(toStringLiteral.(type))("1")>]", this.newWith(<(literal.(type))("1")>).toString());
        Assert.assertEquals("[<(toStringLiteral.(type))("31")>]", this.newWith(<(literal.(type))("31")>).toString());
        Assert.assertEquals("[<(toStringLiteral.(type))("32")>]", this.newWith(<(literal.(type))("32")>).toString());

        <name>Iterable iterable = this.newWith(<["1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue("[<["1", "2"]:(toStringLiteral.(type))(); separator=", ">]".equals(iterable.toString())
                || "[<["2", "1"]:(toStringLiteral.(type))(); separator=", ">]".equals(iterable.toString()));

        <name>Iterable iterable1 = this.newWith(<["0", "31"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable1.toString(),
                iterable1.toString().equals("[<["0", "31"]:(toStringLiteral.(type))(); separator=", ">]")
                        || iterable1.toString().equals("[<["31", "0"]:(toStringLiteral.(type))(); separator=", ">]"));

        <name>Iterable iterable2 = this.newWith(<["31", "32"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable2.toString(),
                iterable2.toString().equals("[<["31", "32"]:(toStringLiteral.(type))(); separator=", ">]")
                        || iterable2.toString().equals("[<["32", "31"]:(toStringLiteral.(type))(); separator=", ">]"));

        <name>Iterable iterable3 = this.newWith(<["32", "33"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable3.toString(),
                iterable3.toString().equals("[<["32", "33"]:(toStringLiteral.(type))(); separator=", ">]")
                        || iterable3.toString().equals("[<["33", "32"]:(toStringLiteral.(type))(); separator=", ">]"));

        <name>Iterable iterable4 = this.newWith(<["0", "1"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable4.toString(),
                iterable4.toString().equals("[<["0", "1"]:(toStringLiteral.(type))(); separator=", ">]")
                        || iterable4.toString().equals("[<["1", "0"]:(toStringLiteral.(type))(); separator=", ">]"));
    }

    @Test
    public void makeString()
    {
        <name>Iterable iterable = this.classUnderTest();
        Assert.assertEquals("<(toStringLiteral.(type))("1")>", this.newWith(<(literal.(type))("1")>).makeString("/"));
        Assert.assertEquals("<(toStringLiteral.(type))("31")>", this.newWith(<(literal.(type))("31")>).makeString());
        Assert.assertEquals("<(toStringLiteral.(type))("32")>", this.newWith(<(literal.(type))("32")>).makeString());
        Assert.assertEquals(iterable.toString(), iterable.makeString("[", ", ", "]"));
        Assert.assertEquals("", this.newWith().makeString());
        Assert.assertEquals("", this.newWith().makeString("/"));
        Assert.assertEquals("[]", this.newWith().makeString("[", ", ", "]"));

        <name>Iterable iterable1 = this.newWith(<["0", "31"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable1.makeString(),
                iterable1.makeString().equals("<["0", "31"]:(toStringLiteral.(type))(); separator=", ">")
                        || iterable1.makeString().equals("<["31", "0"]:(toStringLiteral.(type))(); separator=", ">"));

        <name>Iterable iterable2 = this.newWith(<["31", "32"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable2.makeString("[", "/", "]"),
                iterable2.makeString("[", "/", "]").equals("[<["31", "32"]:(toStringLiteral.(type))(); separator="/">]")
                        || iterable2.makeString("[", "/", "]").equals("[<["32", "31"]:(toStringLiteral.(type))(); separator="/">]"));

        <name>Iterable iterable3 = this.newWith(<["32", "33"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable3.makeString("/"),
                iterable3.makeString("/").equals("<["32", "33"]:(toStringLiteral.(type))(); separator="/">")
                        || iterable3.makeString("/").equals("<["33", "32"]:(toStringLiteral.(type))(); separator="/">"));

        <name>Iterable iterable4 = this.newWith(<["1", "2"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue("<["1", "2"]:(toStringLiteral.(type))(); separator=", ">".equals(iterable4.makeString())
                || "<["2", "1"]:(toStringLiteral.(type))(); separator=", ">".equals(iterable4.makeString()));
        Assert.assertTrue("<["1", "2"]:(toStringLiteral.(type))(); separator="/">".equals(iterable4.makeString("/"))
                || "<["2", "1"]:(toStringLiteral.(type))(); separator="/">".equals(iterable4.makeString("/")));
        Assert.assertTrue("[<["1", "2"]:(toStringLiteral.(type))(); separator="/">]".equals(iterable4.makeString("[", "/", "]"))
                || "[<["2", "1"]:(toStringLiteral.(type))(); separator="/">]".equals(iterable4.makeString("[", "/", "]")));

        <name>Iterable iterable5 = this.newWith(<["0", "1"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(
                iterable5.makeString(),
                iterable5.makeString().equals("<["0", "1"]:(toStringLiteral.(type))(); separator=", ">")
                        || iterable5.makeString().equals("<["1", "0"]:(toStringLiteral.(type))(); separator=", ">"));
        Assert.assertTrue(
                iterable5.makeString("[", "/", "]"),
                iterable5.makeString("[", "/", "]").equals("[<["0", "1"]:(toStringLiteral.(type))(); separator="/">]")
                        || iterable5.makeString("[", "/", "]").equals("[<["1", "0"]:(toStringLiteral.(type))(); separator="/">]"));
        Assert.assertTrue(
                iterable5.makeString("/"),
                iterable5.makeString("/").equals("<["0", "1"]:(toStringLiteral.(type))(); separator="/">")
                        || iterable5.makeString("/").equals("<["1", "0"]:(toStringLiteral.(type))(); separator="/">"));
    }

    @Test
    public void appendString()
    {
        StringBuilder appendable = new StringBuilder();
        this.newWith().appendString(appendable);
        Assert.assertEquals("", appendable.toString());
        this.newWith().appendString(appendable, "/");
        Assert.assertEquals("", appendable.toString());
        this.newWith().appendString(appendable, "[", ", ", "]");
        Assert.assertEquals("[]", appendable.toString());
        StringBuilder appendable1 = new StringBuilder();
        this.newWith(<(literal.(type))("1")>).appendString(appendable1);
        Assert.assertEquals("<(toStringLiteral.(type))("1")>", appendable1.toString());
        StringBuilder appendable2 = new StringBuilder();

        <name>Iterable iterable = this.newWith(<["1", "2"]:(literal.(type))(); separator=", ">);
        iterable.appendString(appendable2);
        Assert.assertTrue("<["1", "2"]:(toStringLiteral.(type))(); separator=", ">".equals(appendable2.toString())
                || "<["2", "1"]:(toStringLiteral.(type))(); separator=", ">".equals(appendable2.toString()));
        StringBuilder appendable3 = new StringBuilder();
        iterable.appendString(appendable3, "/");
        Assert.assertTrue("<["1", "2"]:(toStringLiteral.(type))(); separator="/">".equals(appendable3.toString())
                || "<["2", "1"]:(toStringLiteral.(type))(); separator="/">".equals(appendable3.toString()));
        StringBuilder appendable4 = new StringBuilder();
        iterable.appendString(appendable4, "[", ", ", "]");
        Assert.assertEquals(iterable.toString(), appendable4.toString());

        StringBuilder appendable5 = new StringBuilder();
        this.newWith(<(literal.(type))("31")>).appendString(appendable5);
        Assert.assertEquals("<(toStringLiteral.(type))("31")>", appendable5.toString());

        StringBuilder appendable6 = new StringBuilder();
        this.newWith(<(literal.(type))("32")>).appendString(appendable6);
        Assert.assertEquals("<(toStringLiteral.(type))("32")>", appendable6.toString());

        StringBuilder appendable7 = new StringBuilder();
        <name>Iterable iterable1 = this.newWith(<["0", "31"]:(literal.(type))(); separator=", ">);
        iterable1.appendString(appendable7);
        Assert.assertTrue(appendable7.toString(), "<["0", "31"]:(toStringLiteral.(type))(); separator=", ">".equals(appendable7.toString())
                || "<["31", "0"]:(toStringLiteral.(type))(); separator=", ">".equals(appendable7.toString()));

        StringBuilder appendable8 = new StringBuilder();
        <name>Iterable iterable2 = this.newWith(<["31", "32"]:(literal.(type))(); separator=", ">);
        iterable2.appendString(appendable8, "/");
        Assert.assertTrue(appendable8.toString(), "<["31", "32"]:(toStringLiteral.(type))(); separator="/">".equals(appendable8.toString())
                || "<["32", "31"]:(toStringLiteral.(type))(); separator="/">".equals(appendable8.toString()));

        StringBuilder appendable9 = new StringBuilder();
        <name>Iterable iterable4 = this.newWith(<["32", "33"]:(literal.(type))(); separator=", ">);
        iterable4.appendString(appendable9, "[", "/", "]");
        Assert.assertTrue(appendable9.toString(), "[<["32", "33"]:(toStringLiteral.(type))(); separator="/">]".equals(appendable9.toString())
                || "[<["33", "32"]:(toStringLiteral.(type))(); separator="/">]".equals(appendable9.toString()));

        StringBuilder appendable10 = new StringBuilder();
        <name>Iterable iterable5 = this.newWith(<["0", "1"]:(literal.(type))(); separator=", ">);
        iterable5.appendString(appendable10);
        Assert.assertTrue(appendable10.toString(), "<["0", "1"]:(toStringLiteral.(type))(); separator=", ">".equals(appendable10.toString())
                || "<["1", "0"]:(toStringLiteral.(type))(); separator=", ">".equals(appendable10.toString()));
        StringBuilder appendable11 = new StringBuilder();
        iterable5.appendString(appendable11, "/");
        Assert.assertTrue(appendable11.toString(), "<["0", "1"]:(toStringLiteral.(type))(); separator="/">".equals(appendable11.toString())
                || "<["1", "0"]:(toStringLiteral.(type))(); separator="/">".equals(appendable11.toString()));
        StringBuilder appendable12 = new StringBuilder();
        iterable5.appendString(appendable12, "[", "/", "]");
        Assert.assertTrue(appendable12.toString(), "[<["0", "1"]:(toStringLiteral.(type))(); separator="/">]".equals(appendable12.toString())
                || "[<["1", "0"]:(toStringLiteral.(type))(); separator="/">]".equals(appendable12.toString()));
    }

    @Test
    public void toList()
    {
        <name>Iterable iterable = this.newWith(<["31", "32"]:(literal.(type))(); separator=", ">);
        Assert.assertTrue(<name>ArrayList.newListWith(<["31", "32"]:(literal.(type))(); separator=", ">).equals(iterable.toList())
                || <name>ArrayList.newListWith(<["32", "31"]:(literal.(type))(); separator=", ">).equals(iterable.toList()));
        Assert.assertEquals(<name>ArrayList.newListWith(<(literal.(type))("0")>), this.newWith(<(literal.(type))("0")>).toList());
        Assert.assertEquals(<name>ArrayList.newListWith(<(literal.(type))("31")>), this.newWith(<(literal.(type))("31")>).toList());
        Assert.assertEquals(<name>ArrayList.newListWith(<(literal.(type))("32")>), this.newWith(<(literal.(type))("32")>).toList());
        Assert.assertEquals(new <name>ArrayList(), this.newWith().toList());
    }

    @Test
    public void toSortedList()
    {
        Assert.assertEquals(<name>ArrayList.newListWith(), this.newWith().toSortedList());
        Assert.assertEquals(<name>ArrayList.newListWith(<(literal.(type))("1")>), this.newWith(<(literal.(type))("1")>).toSortedList());
        Assert.assertEquals(<name>ArrayList.newListWith(<["0", "1", "31"]:(literal.(type))(); separator=", ">), this.newWith(<["0", "31", "1"]:(literal.(type))(); separator=", ">).toSortedList());
        Assert.assertEquals(<name>ArrayList.newListWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">), this.newWith(<["0", "31", "32", "1"]:(literal.(type))(); separator=", ">).toSortedList());
    }

    @Test
    public void toSet()
    {
        Assert.assertEquals(<name>HashSet.newSetWith(), this.newWith().toSet());
        Assert.assertEquals(<name>HashSet.newSetWith(<["1"]:(literal.(type))(); separator=", ">), this.newWith(<(literal.(type))("1")>).toSet());
        Assert.assertEquals(<name>HashSet.newSetWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).toSet());
        Assert.assertEquals(<name>HashSet.newSetWith(<["0", "1", "31"]:(literal.(type))(); separator=", ">), this.newWith(<["0", "1", "31"]:(literal.(type))(); separator=", ">).toSet());
        Assert.assertEquals(<name>HashSet.newSetWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">), this.newWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">).toSet());
        Assert.assertEquals(<name>HashSet.newSetWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">).toSet());
    }

    @Test
    public void toBag()
    {
        Assert.assertEquals(new <name>HashBag(), this.newWith().toBag());
        Assert.assertEquals(<name>HashBag.newBagWith(<["1"]:(literal.(type))(); separator=", ">), this.newWith(<(literal.(type))("1")>).toBag());
        Assert.assertEquals(<name>HashBag.newBagWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "3"]:(literal.(type))(); separator=", ">).toBag());
        Assert.assertEquals(<name>HashBag.newBagWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">), this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">).toBag());
        Assert.assertEquals(<name>HashBag.newBagWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">), this.newWith(<["0", "1", "31", "32"]:(literal.(type))(); separator=", ">).toBag());
    }

    @Test
    public void asLazy()
    {
        <name>Iterable iterable = this.classUnderTest();
        Assert.assertEquals(iterable.toBag(), iterable.asLazy().toBag());
        Verify.assertInstanceOf(Lazy<name>Iterable.class, iterable.asLazy());

        <name>Iterable iterable1 = this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(iterable1.toBag(), iterable1.asLazy().toBag());
        Verify.assertInstanceOf(Lazy<name>Iterable.class, iterable1.asLazy());

        <name>Iterable iterable2 = this.newWith(<["1", "2", "2", "3", "3", "3"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(iterable2.toBag(), iterable2.asLazy().toBag());
        Verify.assertInstanceOf(Lazy<name>Iterable.class, iterable2.asLazy());

        <name>Iterable iterable3 = this.newWith();
        Assert.assertEquals(iterable3.toBag(), iterable3.asLazy().toBag());
        Verify.assertInstanceOf(Lazy<name>Iterable.class, iterable3.asLazy());

        <name>Iterable iterable4 = this.newWith(<["1"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(iterable4.toBag(), iterable4.asLazy().toBag());
        Verify.assertInstanceOf(Lazy<name>Iterable.class, iterable4.asLazy());
    }

    @Test
    public void injectInto()
    {
        <name>Iterable iterable1 = this.newWith(<["0", "2", "31"]:(literal.(type))(); separator=", ">);
        <wrapperName> sum1 = iterable1.injectInto(<wrapperName>.valueOf(<(literal.(type))("0")>), (<wrapperName> result, <type> value) -> <wrapperName>.valueOf((<type>) (result + value + 1)));
        Assert.assertEquals(<wrapperName>.valueOf(<(literal.(type))("36")>), sum1);

        <name>Iterable iterable2 = this.newWith(<[ "1", "2", "31"]:(literal.(type))(); separator=", ">);
        <wrapperName> sum2 = iterable2.injectInto(<wrapperName>.valueOf(<(literal.(type))("0")>), (<wrapperName> result, <type> value) -> <wrapperName>.valueOf((<type>) (result + value + 1)));
        Assert.assertEquals(<wrapperName>.valueOf(<(literal.(type))("37")>), sum2);

        <name>Iterable iterable3 = this.newWith(<["0", "1", "2", "31"]:(literal.(type))(); separator=", ">);
        <wrapperName> sum3 = iterable3.injectInto(<wrapperName>.valueOf(<(literal.(type))("0")>), (<wrapperName> result, <type> value) -> <wrapperName>.valueOf((<type>) (result + value + 1)));
        Assert.assertEquals(<wrapperName>.valueOf(<(literal.(type))("38")>), sum3);
    }

    @Test(expected = NoSuchElementException.class)
    public void reduceOnEmptyThrows()
    {
        this.newWith().reduce((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>);
    }

    @Test
    public void reduce()
    {
        <name>Iterable iterable1 = this.newWith(<["0", "2", "31"]:(literal.(type))(); separator=", ">);
        <(wideType.(type))> sum1 = iterable1.reduce((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>);
        Assert.assertEquals(<(wideLiteral.(type))("35")>, sum1<if(primitive.floatingPoint)>, 0.001<endif>);

        <name>Iterable iterable2 = this.newWith(<[ "1", "2", "31"]:(literal.(type))(); separator=", ">);
        <(wideType.(type))> sum2 = iterable2.reduce((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>);
        Assert.assertEquals(<(wideLiteral.(type))("36")>, sum2<if(primitive.floatingPoint)>, 0.001<endif>);

        <name>Iterable iterable3 = this.newWith(<["0", "1", "2", "31"]:(literal.(type))(); separator=", ">);
        <(wideType.(type))> sum3 = iterable3.reduce((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>);
        Assert.assertEquals(<(wideLiteral.(type))("37")>, sum3<if(primitive.floatingPoint)>, 0.001<endif>);
    }

    @Test
    public void reduceIfEmpty()
    {
        <(wideType.(type))> empty1 = this.newWith().reduceIfEmpty((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>, <(wideLiteral.(type))("1")>);
        Assert.assertEquals(<(wideLiteral.(type))("1")>, empty1<if(primitive.floatingPoint)>, 0.001<endif>);
        <(wideType.(type))> empty2 = this.newWith().reduceIfEmpty((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>, <(wideLiteral.(type))("0")>);
        Assert.assertEquals(<(wideLiteral.(type))("0")>, empty2<if(primitive.floatingPoint)>, 0.001<endif>);

        <name>Iterable iterable1 = this.newWith(<["0", "2", "31"]:(literal.(type))(); separator=", ">);
        <(wideType.(type))> sum1 = iterable1.reduceIfEmpty((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>, <(wideLiteral.(type))("0")>);
        Assert.assertEquals(<(wideLiteral.(type))("35")>, sum1<if(primitive.floatingPoint)>, 0.001<endif>);

        <name>Iterable iterable2 = this.newWith(<[ "1", "2", "31"]:(literal.(type))(); separator=", ">);
        <(wideType.(type))> sum2 = iterable2.reduceIfEmpty((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>, <(wideLiteral.(type))("0")>);
        Assert.assertEquals(<(wideLiteral.(type))("36")>, sum2<if(primitive.floatingPoint)>, 0.001<endif>);

        <name>Iterable iterable3 = this.newWith(<["0", "1", "2", "31"]:(literal.(type))(); separator=", ">);
        <(wideType.(type))> sum3 = iterable3.reduceIfEmpty((<(wideType.(type))> result, <type> value) -> <(castWideType.(type))>result + <(castWideType.(type))>value + <(wideLiteral.(type))("1")>, <(wideLiteral.(type))("0")>);
        Assert.assertEquals(<(wideLiteral.(type))("37")>, sum3<if(primitive.floatingPoint)>, 0.001<endif>);
    }

    @Test
    public void chunk()
    {
        <name>Iterable iterable = this.newWith(<["0", "1", "2", "3", "4", "5"]:(literal.(type))(); separator=", ">);
        Assert.assertEquals(
                Lists.mutable.with(
                        this.newMutableCollectionWith(<["0"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["1"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["2"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["3"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["4"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["5"]:(literal.(type))(); separator=", ">)).toSet(),
                iterable.chunk(1).toSet());
        Assert.assertEquals(
                Lists.mutable.with(
                        this.newMutableCollectionWith(<["0", "1"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["2", "3"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["4", "5"]:(literal.(type))(); separator=", ">)).toSet(),
                iterable.chunk(2).toSet());
        Assert.assertEquals(
                Lists.mutable.with(
                        this.newMutableCollectionWith(<["0", "1", "2"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["3", "4", "5"]:(literal.(type))(); separator=", ">)).toSet(),
                iterable.chunk(3).toSet());
        Assert.assertEquals(
                Lists.mutable.with(
                        this.newMutableCollectionWith(<["0", "1", "2", "3"]:(literal.(type))(); separator=", ">),
                        this.newMutableCollectionWith(<["4", "5"]:(literal.(type))(); separator=", ">)).toSet(),
                iterable.chunk(4).toSet());
        Assert.assertEquals(
                Lists.mutable.with(this.newMutableCollectionWith(<["0", "1", "2", "3", "4", "5"]:(literal.(type))(); separator=", ">)).toSet(),
                iterable.chunk(6).toSet());
        Assert.assertEquals(
                Lists.mutable.with(this.newMutableCollectionWith(<["0", "1", "2", "3", "4", "5"]:(literal.(type))(); separator=", ">)).toSet(),
                iterable.chunk(7).toSet());
        Assert.assertEquals(Lists.mutable.with(), this.newWith().chunk(1));
        Assert.assertEquals(Lists.mutable.with(this.newMutableCollectionWith(<["0"]:(literal.(type))(); separator=", ">)), this.newWith(<["0"]:(literal.(type))(); separator=", ">).chunk(1));
        Assert.assertEquals(Lists.mutable.with(), this.newWith().chunk(1));

        Verify.assertThrows(IllegalArgumentException.class, () -> iterable.chunk(0));
        Verify.assertThrows(IllegalArgumentException.class, () -> iterable.chunk(-1));
        Verify.assertThrows(IllegalArgumentException.class, () -> this.newMutableCollectionWith().chunk(-1));
    }
}

>>

kahanSumTests ::= [
    "float": "kahanFloatSumTest",
    "double": "kahanDoubleSumTest",
    "default": "noTest"
]

kahanFloatSumTest() ::= <<
>>

kahanDoubleSumTest() ::= <<

>>

noTest() ::= ""

maxTests ::= [
    "byte": "intMaxTest",
    "short": "intMaxTest",
    "char": "charMaxTest",
    "int": "intMaxTest",
    "long": "intMaxTest",
    "float": "floatMaxTest",
    "double": "floatMaxTest"
]

intMaxTest(type, name) ::= <<
Assert.assertEquals(<(wideLiteral.(type))("9")>, this.newWith(<["-1", "-2", "9"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("-1")>, this.newWith(<["-1", "-2", "-9"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("32")>, this.newWith(<["1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("32")>, this.newWith(<["-1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("31")>, this.newWith(<["31", "0", "30"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("39")>, this.newWith(<["32", "39", "35"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(this.classUnderTest().size(), this.classUnderTest().max()<(delta.(type))>);
>>

charMaxTest(type, name) ::= <<
Assert.assertEquals(<(literal.(type))("-1")>, this.newWith(<["-1", "-2", "9"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(literal.(type))("32")>, this.newWith(<["1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(literal.(type))("-1")>, this.newWith(<["-1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(literal.(type))("31")>, this.newWith(<["31", "0", "30"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<(literal.(type))("39")>, this.newWith(<["32", "39", "35"]:(literal.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(this.classUnderTest().size(), this.classUnderTest().max()<(wideDelta.(type))>);
>>

floatMaxTest(type, name) ::= <<
<intMaxTest(type, name)>
Assert.assertEquals(32.5, this.newWith(<["-1.5", "31.8", "32.5"]:(decimalLiteral.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(-1.5, this.newWith(<["-1.5", "-31.8", "-32.5"]:(decimalLiteral.(type))(); separator=", ">).max()<(wideDelta.(type))>);
Assert.assertEquals(<name>.POSITIVE_INFINITY, this.newWith(<["-1.5", "31.8", "32.5"]:(decimalLiteral.(type))(); separator=", ">, <name>.POSITIVE_INFINITY).max()<(wideDelta.(type))>);
Assert.assertEquals(<name>.NaN, this.newWith(<["-1.5", "31.8", "32.5"]:(decimalLiteral.(type))(); separator=", ">, <name>.NaN, 31.5f).max()<(wideDelta.(type))>);
Assert.assertEquals(32.5, this.newWith(<["-1.5", "31.8", "32.5"]:(decimalLiteral.(type))(); separator=", ">, <name>.NEGATIVE_INFINITY, 31.5f).max()<(wideDelta.(type))>);
>>

minTests ::= [
    "byte": "intMinTest",
    "short": "intMinTest",
    "char": "charMinTest",
    "int": "intMinTest",
    "long": "intMinTest",
    "float": "floatMinTest",
    "double": "floatMinTest"
]

intMinTest(type, name) ::= <<
Assert.assertEquals(<(wideLiteral.(type))("-2")>, this.newWith(<["-1", "-2", "9"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("0")>, this.newWith(<["1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("-1")>, this.newWith(<["-1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("31")>, this.newWith(<["31", "32", "33"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("32")>, this.newWith(<["32", "39", "35"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("1")>, this.classUnderTest().min()<(wideDelta.(type))>);
>>

charMinTest(type, name) ::= <<
Assert.assertEquals(<(wideLiteral.(type))("9")>, this.newWith(<["-1", "-2", "9"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("0")>, this.newWith(<["1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("0")>, this.newWith(<["-1", "0", "9", "30", "31", "32"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("31")>, this.newWith(<["31", "32", "33"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("32")>, this.newWith(<["32", "39", "35"]:(literal.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(<(wideLiteral.(type))("1")>, this.classUnderTest().min()<(wideDelta.(type))>);
>>

floatMinTest(type, name) ::= <<
<intMinTest(type, name)>
Assert.assertEquals(-1.5, this.newWith(<["-1.5", "31.5", "32.5"]:(decimalLiteral.(type))(); separator=", ">).min()<(wideDelta.(type))>);
Assert.assertEquals(1.5, this.newWith(<["1.5", "31.0", "30.0"]:(decimalLiteral.(type))(); separator=", ">, <name>.POSITIVE_INFINITY).min()<(wideDelta.(type))>);
Assert.assertEquals(31.5, this.newWith(<["31.5", "32.5"]:(decimalLiteral.(type))(); separator=", ">, <name>.NaN).min()<(wideDelta.(type))>);
Assert.assertEquals(<name>.NEGATIVE_INFINITY, this.newWith(<["-1.5", "31.5", "32.5"]:(decimalLiteral.(type))(); separator=", ">, <name>.NEGATIVE_INFINITY, 31.5f).min()<(wideDelta.(type))>);
>>

NaNTests(key) ::= <<
@Test
public void contains_<key>()
{
    <name>Iterable primitiveIterable = this.newWith(<wrapperName>.<key>);
    Set\<<wrapperName>\> hashSet = new HashSet\<>();
    Assert.assertTrue(hashSet.add(<wrapperName>.<key>));
    Assert.assertTrue(hashSet.contains(<wrapperName>.<key>));
    Assert.assertTrue(primitiveIterable.contains(<wrapperName>.<key>));
}

>>

NaNEqualsTests() ::= <<
@Test
public void testEquals_NaN()
{
    <name>Iterable iterable1 = this.newWith(<wrapperName>.NaN);
    Set\<<wrapperName>\> hashSet1 = new HashSet\<>();
    hashSet1.add(<wrapperName>.NaN);
    <name>Iterable iterable2 = this.newWith(<wrapperName>.NaN);
    Set\<<wrapperName>\> hashSet2 = new HashSet\<>();
    hashSet2.add(<wrapperName>.NaN);
    <name>Iterable iterable3 = this.newWith(<wrapperName>.POSITIVE_INFINITY);
    Set\<<wrapperName>\> hashSet3 = new HashSet\<>();
    hashSet3.add(<wrapperName>.POSITIVE_INFINITY);
    <name>Iterable iterable4 = this.newWith(<wrapperName>.POSITIVE_INFINITY);
    Set\<<wrapperName>\> hashSet4 = new HashSet\<>();
    hashSet4.add(<wrapperName>.POSITIVE_INFINITY);
    <name>Iterable iterable5 = this.newWith(<wrapperName>.NEGATIVE_INFINITY);
    Set\<<wrapperName>\> hashSet5 = new HashSet\<>();
    hashSet5.add(<wrapperName>.NEGATIVE_INFINITY);
    <name>Iterable iterable6 = this.newWith(<wrapperName>.NEGATIVE_INFINITY);
    Set\<<wrapperName>\> hashSet6 = new HashSet\<>();
    hashSet6.add(<wrapperName>.NEGATIVE_INFINITY);

    Assert.assertEquals(hashSet1, hashSet2);
    Assert.assertEquals(iterable1, iterable2);
    Assert.assertEquals(hashSet3, hashSet4);
    Assert.assertEquals(iterable3, iterable4);
    Assert.assertEquals(hashSet5, hashSet6);
    Assert.assertEquals(iterable5, iterable6);

    Assert.assertNotEquals(hashSet1, hashSet3);
    Assert.assertNotEquals(iterable1, iterable3);
    Assert.assertNotEquals(hashSet3, hashSet5);
    Assert.assertNotEquals(iterable3, iterable5);
    Assert.assertNotEquals(hashSet5, hashSet1);
    Assert.assertNotEquals(iterable5, iterable1);
}

>>

differentNaNs() ::= <<
@Test
public void contains_different_NaNs()
{
    <bitsType.(type)> nan1 = <NaNBits1.(type)>;
    <name>Iterable primitiveIterable = this.newWith(<wrapperName>.<bitsType.(type)>BitsTo<name>(nan1));
    Set\<<wrapperName>\> hashSet = new HashSet\<>();
    hashSet.add(<wrapperName>.<bitsType.(type)>BitsTo<name>(nan1));
    <bitsType.(type)> nan2 = <NaNBits2.(type)>;
    Assert.assertEquals(hashSet.contains(<wrapperName>.<bitsType.(type)>BitsTo<name>(nan2)), primitiveIterable.contains(<wrapperName>.<bitsType.(type)>BitsTo<name>(nan2)));
}

>>

ZeroTests() ::= <<
@Test
public void contains_zero()
{
    <name>Iterable iterable = this.newWith(<(literal.(type))("0")>);
    Set\<<wrapperName>\> hashSet = new HashSet\<>();
    hashSet.add(<(literal.(type))("0")>);

    Assert.assertTrue(hashSet.contains(<(literal.(type))("0")>));
    Assert.assertFalse(hashSet.contains(-<(literal.(type))("0")>));
    Assert.assertTrue(iterable.contains(<(literal.(type))("0")>));
    Assert.assertFalse(iterable.contains(-<(literal.(type))("0")>));
}

>>

NaNBits1 ::= [
    "float": "0x7f800001",
    "double": "0x7ff0000000000001L",
    "default": "no matching bits"
]

NaNBits2 ::= [
    "float": "0xff800001",
    "double": "0xfff0000000000001L",
    "default": "no matching bits"
]
