// Path: test/com/googlecode/yatspec/fixture/VarargFixture.java
// @SuppressWarnings("unused")
// public class VarargFixture {
// 
//     public Map<String, Object> arrayOnly(String[] lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// 
//     public Map<String, Object> varargsOnly(String... lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// 
//     public Map<String, Object> oneParamAndVarargs(String someParam, String... lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("someParam", someParam);
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// 
//     public Map<String, Object> someParamsAndVarargs(String someParam, String anotherParam, String... lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("someParam", someParam);
//         recordedParams.put("anotherParam", anotherParam);
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// }
// 
// Path: test/com/googlecode/yatspec/junit/DecoratingFrameworkMethodTest.java
// static Row row(final List<String> args) {
//     return new Row() {
//         @Override
//         public String[] value() {
//             return args.toArray(new String[0]);
//         }
// 
//         @Override
//         public Class<? extends Annotation> annotationType() {
//             throw new UnsupportedOperationException("Not yet implemented");
//         }
//     };
// }


import com.googlecode.totallylazy.Mapper;
import com.googlecode.totallylazy.Predicates;
import com.googlecode.yatspec.fixture.VarargFixture;
import org.junit.Test;
import org.junit.runners.model.FrameworkMethod;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.yatspec.junit.DecoratingFrameworkMethodTest.row;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContaining;
        }, Predicates.is(methodName))).headOption().getOrThrow(new RuntimeException("Couldn't find method called " + methodName));
    }

    public void testVarargsForMethod(Method underTest) throws Throwable {
        final List<String> varArgs = asList("a", "b", "c");
        final List<String> params = new ArrayList<String>();
        if (underTest.getParameterTypes().length > 1) {
            params.add("someParam");
        }
        if (underTest.getParameterTypes().length > 2) {
            params.add("anotherParam");
        }

        checkVarargs(underTest, asList("a"), params);

        checkVarargs(underTest, varArgs, params);

        checkNonVarargs(underTest, params);
    }

    private void checkVarargs(Method underTest, List<String> varArgs, List<String> params) throws Throwable {
        final List<String> paramsToUse = sequence(params).join(varArgs).toList();
        final Map<String, Object> result = checkNonVarargs(underTest, paramsToUse);

        assertThat((String[])result.get("lotsOfParams"), arrayContaining(varArgs.toArray()));
    }

    private Map<String, Object> checkNonVarargs(Method underTest, List<String> params) throws Throwable {
        DecoratingFrameworkMethod decoratingFrameworkMethod = new DecoratingFrameworkMethod(new FrameworkMethod(underTest), row(params));

// Path: test/com/googlecode/yatspec/fixture/VarargFixture.java
// @SuppressWarnings("unused")
// public class VarargFixture {
// 
//     public Map<String, Object> arrayOnly(String[] lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// 
//     public Map<String, Object> varargsOnly(String... lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// 
//     public Map<String, Object> oneParamAndVarargs(String someParam, String... lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("someParam", someParam);
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// 
//     public Map<String, Object> someParamsAndVarargs(String someParam, String anotherParam, String... lotsOfParams) {
//         Map<String, Object> recordedParams = new HashMap<String, Object>();
//         recordedParams.put("someParam", someParam);
//         recordedParams.put("anotherParam", anotherParam);
//         recordedParams.put("lotsOfParams", lotsOfParams);
//         return recordedParams;
//     }
// }
// 
// Path: test/com/googlecode/yatspec/junit/DecoratingFrameworkMethodTest.java
// static Row row(final List<String> args) {
//     return new Row() {
//         @Override
//         public String[] value() {
//             return args.toArray(new String[0]);
//         }
// 
//         @Override
//         public Class<? extends Annotation> annotationType() {
//             throw new UnsupportedOperationException("Not yet implemented");
//         }
//     };
// }


// Path: test/com/googlecode/yatspec/junit/DecoratingFrameworkMethodVarargsTest.java
import com.googlecode.totallylazy.Mapper;
import com.googlecode.totallylazy.Predicates;
import com.googlecode.yatspec.fixture.VarargFixture;
import org.junit.Test;
import org.junit.runners.model.FrameworkMethod;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.yatspec.junit.DecoratingFrameworkMethodTest.row;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContaining;

        }, Predicates.is(methodName))).headOption().getOrThrow(new RuntimeException("Couldn't find method called " + methodName));
    }

    public void testVarargsForMethod(Method underTest) throws Throwable {
        final List<String> varArgs = asList("a", "b", "c");
        final List<String> params = new ArrayList<String>();
        if (underTest.getParameterTypes().length > 1) {
            params.add("someParam");
        }
        if (underTest.getParameterTypes().length > 2) {
            params.add("anotherParam");
        }

        checkVarargs(underTest, asList("a"), params);

        checkVarargs(underTest, varArgs, params);

        checkNonVarargs(underTest, params);
    }

    private void checkVarargs(Method underTest, List<String> varArgs, List<String> params) throws Throwable {
        final List<String> paramsToUse = sequence(params).join(varArgs).toList();
        final Map<String, Object> result = checkNonVarargs(underTest, paramsToUse);

        assertThat((String[])result.get("lotsOfParams"), arrayContaining(varArgs.toArray()));
    }

    private Map<String, Object> checkNonVarargs(Method underTest, List<String> params) throws Throwable {
        DecoratingFrameworkMethod decoratingFrameworkMethod = new DecoratingFrameworkMethod(new FrameworkMethod(underTest), row(params));

        final Map<String, Object> result = (Map<String, Object>) decoratingFrameworkMethod.invokeExplosively(new VarargFixture());