// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/parametersets/BasicParameterList.java
// public final class BasicParameterList implements ParameterList
// {
//     private final Iterable<Parameter> mParameters;
// 
// 
//     public BasicParameterList(Parameter... parameters)
//     {
//         this(Arrays.asList(parameters.clone()));
//     }
// 
// 
//     /**
//      * Creates a {@link ParameterList} from the given {@link Iterable} or {@link Parameter}s. The given {@link Iterable} must be immutable.
//      *
//      * @param parameters
//      *         An immutable {@link Iterable} of {@link Parameter}s.
//      */
//     public BasicParameterList(Iterable<Parameter> parameters)
//     {
//         mParameters = parameters;
//     }
// 
// 
//     @Override
//     public Iterator<Parameter> iterator()
//     {
//         return mParameters.iterator();
//     }
// }
// 
// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/parametersets/Fluent.java
// public final class Fluent implements FluentParameterList
// {
//     private final ParameterList mDelegate;
// 
// 
//     public Fluent()
//     {
//         this(EmptyParameterList.INSTANCE);
//     }
// 
// 
//     public Fluent(ParameterList delegate)
//     {
//         mDelegate = delegate;
//     }
// 
// 
//     @Override
//     public FluentParameterList alsoWith(Parameter... parameters)
//     {
//         return new Fluent(new Appending(mDelegate, parameters));
//     }
// 
// 
//     @Override
//     public FluentParameterList ratherWith(Parameter... parameters)
//     {
//         return new Fluent(new Replacing(mDelegate, parameters));
//     }
// 
// 
//     @Override
//     public FluentParameterList without(ParameterType<?>... types)
//     {
//         return new Fluent(new Removing(mDelegate, types));
//     }
// 
// 
//     @Override
//     public Iterator<Parameter> iterator()
//     {
//         return mDelegate.iterator();
//     }
// }
// 
// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/parametertypes/BasicParameterType.java
// public final class BasicParameterType<T> implements ParameterType<T>
// {
//     private final CharSequence mName;
//     private final ValueType<T> mValueType;
// 
// 
//     /**
//      * Creates a {@link ParameterType} with the given name and {@link ValueType}.
//      *
//      * @param name
//      * @param valueType
//      */
//     public BasicParameterType(CharSequence name, ValueType<T> valueType)
//     {
//         mName = name;
//         mValueType = valueType;
//     }
// 
// 
//     @Override
//     public CharSequence name()
//     {
//         return mName;
//     }
// 
// 
//     @Override
//     public T value(Parameter parameter)
//     {
//         if (!name().toString().equals(parameter.name().toString()))
//         {
//             throw new IllegalArgumentException(
//                     String.format("Given parameter has wrong type \"%s\". Expected type \"%s\"", parameter.name().toString(), mName.toString()));
//         }
//         return mValueType.parsedValue(parameter.textValue());
//     }
// 
// 
//     @Override
//     public Parameter parameter(final T value)
//     {
//         return new Parameter()
//         {
//             @Override
//             public CharSequence name()
//             {
//                 return mName;
//             }
// 
// 
//             @Override
//             public CharSequence textValue()
//             {
//                 return mValueType.serializedValue(value);
//             }
//         };
//     }
// }
// 
// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/valuetypes/TextValueType.java
// public final class TextValueType implements ValueType<CharSequence>
// {
//     public final static TextValueType INSTANCE = new TextValueType();
// 
// 
//     @Override
//     public CharSequence parsedValue(CharSequence valueText)
//     {
//         return valueText;
//     }
// 
// 
//     @Override
//     public CharSequence serializedValue(CharSequence value)
//     {
//         return value;
//     }
// }


import org.dmfs.rfc3986.parameters.parametersets.BasicParameterList;
import org.dmfs.rfc3986.parameters.parametersets.Fluent;
import org.dmfs.rfc3986.parameters.parametertypes.BasicParameterType;
import org.dmfs.rfc3986.parameters.valuetypes.TextValueType;
import org.junit.Test;
import java.util.Iterator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
    public void alsoWith2() throws Exception
    {
        ValueType<CharSequence> valueType = new TextValueType();
        ParameterType<CharSequence> textParam = new BasicParameterType<>("test", valueType);
        ParameterType<CharSequence> textParam2 = new BasicParameterType<>("q", valueType);

        FluentParameterList fluentParams = new Fluent(new BasicParameterList(textParam.parameter("x"), textParam2.parameter("y")));
        fluentParams = fluentParams.alsoWith(textParam.parameter("123"));
        fluentParams = fluentParams.alsoWith(textParam.parameter("abc"));
        fluentParams = fluentParams.alsoWith(textParam.parameter("def"));

        // all values should have been added
        Iterator<Parameter> params = fluentParams.iterator();
        Parameter param = params.next();
        assertEquals("test", param.name().toString());
        assertEquals("x", param.textValue().toString());

        param = params.next();
        assertEquals("q", param.name().toString());
        assertEquals("y", param.textValue().toString());

        param = params.next();
        assertEquals("test", param.name().toString());
        assertEquals("123", param.textValue().toString());

        param = params.next();
        assertEquals("test", param.name().toString());
        assertEquals("abc", param.textValue().toString());

        param = params.next();
// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/parametersets/BasicParameterList.java
// public final class BasicParameterList implements ParameterList
// {
//     private final Iterable<Parameter> mParameters;
// 
// 
//     public BasicParameterList(Parameter... parameters)
//     {
//         this(Arrays.asList(parameters.clone()));
//     }
// 
// 
//     /**
//      * Creates a {@link ParameterList} from the given {@link Iterable} or {@link Parameter}s. The given {@link Iterable} must be immutable.
//      *
//      * @param parameters
//      *         An immutable {@link Iterable} of {@link Parameter}s.
//      */
//     public BasicParameterList(Iterable<Parameter> parameters)
//     {
//         mParameters = parameters;
//     }
// 
// 
//     @Override
//     public Iterator<Parameter> iterator()
//     {
//         return mParameters.iterator();
//     }
// }
// 
// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/parametersets/Fluent.java
// public final class Fluent implements FluentParameterList
// {
//     private final ParameterList mDelegate;
// 
// 
//     public Fluent()
//     {
//         this(EmptyParameterList.INSTANCE);
//     }
// 
// 
//     public Fluent(ParameterList delegate)
//     {
//         mDelegate = delegate;
//     }
// 
// 
//     @Override
//     public FluentParameterList alsoWith(Parameter... parameters)
//     {
//         return new Fluent(new Appending(mDelegate, parameters));
//     }
// 
// 
//     @Override
//     public FluentParameterList ratherWith(Parameter... parameters)
//     {
//         return new Fluent(new Replacing(mDelegate, parameters));
//     }
// 
// 
//     @Override
//     public FluentParameterList without(ParameterType<?>... types)
//     {
//         return new Fluent(new Removing(mDelegate, types));
//     }
// 
// 
//     @Override
//     public Iterator<Parameter> iterator()
//     {
//         return mDelegate.iterator();
//     }
// }
// 
// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/parametertypes/BasicParameterType.java
// public final class BasicParameterType<T> implements ParameterType<T>
// {
//     private final CharSequence mName;
//     private final ValueType<T> mValueType;
// 
// 
//     /**
//      * Creates a {@link ParameterType} with the given name and {@link ValueType}.
//      *
//      * @param name
//      * @param valueType
//      */
//     public BasicParameterType(CharSequence name, ValueType<T> valueType)
//     {
//         mName = name;
//         mValueType = valueType;
//     }
// 
// 
//     @Override
//     public CharSequence name()
//     {
//         return mName;
//     }
// 
// 
//     @Override
//     public T value(Parameter parameter)
//     {
//         if (!name().toString().equals(parameter.name().toString()))
//         {
//             throw new IllegalArgumentException(
//                     String.format("Given parameter has wrong type \"%s\". Expected type \"%s\"", parameter.name().toString(), mName.toString()));
//         }
//         return mValueType.parsedValue(parameter.textValue());
//     }
// 
// 
//     @Override
//     public Parameter parameter(final T value)
//     {
//         return new Parameter()
//         {
//             @Override
//             public CharSequence name()
//             {
//                 return mName;
//             }
// 
// 
//             @Override
//             public CharSequence textValue()
//             {
//                 return mValueType.serializedValue(value);
//             }
//         };
//     }
// }
// 
// Path: rfc3986-uri/src/main/java/org/dmfs/rfc3986/parameters/valuetypes/TextValueType.java
// public final class TextValueType implements ValueType<CharSequence>
// {
//     public final static TextValueType INSTANCE = new TextValueType();
// 
// 
//     @Override
//     public CharSequence parsedValue(CharSequence valueText)
//     {
//         return valueText;
//     }
// 
// 
//     @Override
//     public CharSequence serializedValue(CharSequence value)
//     {
//         return value;
//     }
// }


// Path: rfc3986-uri/src/test/java/org/dmfs/rfc3986/parameters/FluentTest.java
import org.dmfs.rfc3986.parameters.parametersets.BasicParameterList;
import org.dmfs.rfc3986.parameters.parametersets.Fluent;
import org.dmfs.rfc3986.parameters.parametertypes.BasicParameterType;
import org.dmfs.rfc3986.parameters.valuetypes.TextValueType;
import org.junit.Test;
import java.util.Iterator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

    public void alsoWith2() throws Exception
    {
        ValueType<CharSequence> valueType = new TextValueType();
        ParameterType<CharSequence> textParam = new BasicParameterType<>("test", valueType);
        ParameterType<CharSequence> textParam2 = new BasicParameterType<>("q", valueType);

        FluentParameterList fluentParams = new Fluent(new BasicParameterList(textParam.parameter("x"), textParam2.parameter("y")));
        fluentParams = fluentParams.alsoWith(textParam.parameter("123"));
        fluentParams = fluentParams.alsoWith(textParam.parameter("abc"));
        fluentParams = fluentParams.alsoWith(textParam.parameter("def"));

        // all values should have been added
        Iterator<Parameter> params = fluentParams.iterator();
        Parameter param = params.next();
        assertEquals("test", param.name().toString());
        assertEquals("x", param.textValue().toString());

        param = params.next();
        assertEquals("q", param.name().toString());
        assertEquals("y", param.textValue().toString());

        param = params.next();
        assertEquals("test", param.name().toString());
        assertEquals("123", param.textValue().toString());

        param = params.next();
        assertEquals("test", param.name().toString());
        assertEquals("abc", param.textValue().toString());

        param = params.next();
        assertEquals("test", param.name().toString());