// Path: spockito-table/src/main/java/org/tools4j/spockito/table/Converters.java
// public static class CollectionConverter implements ValueConverter {
//     private final ValueConverter elementConverter;
//     public CollectionConverter(final ValueConverter elementConverter) {
//         this.elementConverter = requireNonNull(elementConverter);
//     }
// 
//     @Override
//     public <T> T convert(final Class<T> type, final Type genericType, final String value) {
//         if (!Collection.class.isAssignableFrom(type)) {
//             throw new IllegalArgumentException("Type must be a collection: " + type.getName());
//         }
//         final ActualType elementType = actualTypeForTypeParam(genericType, 0, 1);
//         final List<?> list = toList(elementType, value);
//         return convert(type, genericType, list, value);
//     }
// 
//     public <T> T convert(final Class<T> type, final Type genericType, final List<?> list) {
//         return convert(type, genericType, list, list);
//     }
// 
//     public <T> T convert(final Class<T> type, final Type genericType, final List<?> list, final Object value) {
//         if (type.isInstance(list)) {
//             return type.cast(list);
//         }
//         if (type.isAssignableFrom(ArrayList.class)) {
//             return type.cast(new ArrayList<>(list));
//         }
//         if (type.isAssignableFrom(Vector.class)) {
//             return type.cast(new Vector<>(list));
//         }
//         if (type.isAssignableFrom(LinkedList.class)) {
//             return type.cast(new LinkedList<>(list));
//         }
//         if (type.isAssignableFrom(ArrayDeque.class)) {
//             return type.cast(new ArrayDeque<>(list));
//         }
//         if (type.isAssignableFrom(LinkedHashSet.class)) {
//             return type.cast(new LinkedHashSet<>(list));
//         }
//         if (type.isAssignableFrom(TreeSet.class)) {
//             return type.cast(new TreeSet<>(list));
//         }
//         if (type.isAssignableFrom(HashSet.class)) {
//             return type.cast(new HashSet<>(list));
//         }
//         if (type.isAssignableFrom(EnumSet.class)) {
//             final ActualType elementType = actualTypeForTypeParam(genericType, 0, 1);
//             final EnumSet<?> enumSet = enumSet(elementType.rawType().asSubclass(Enum.class), list);
//             return type.cast(enumSet);
//         }
//         if (type.isAssignableFrom(ConcurrentLinkedQueue.class)) {
//             return type.cast(new ConcurrentLinkedQueue<>(list));
//         }
//         if (type.isAssignableFrom(ConcurrentLinkedDeque.class)) {
//             return type.cast(new ConcurrentLinkedDeque<>(list));
//         }
//         if (type.isAssignableFrom(ConcurrentSkipListSet.class)) {
//             return type.cast(new ConcurrentSkipListSet<>(list));
//         }
//         //unsupported collection type
//         throw new IllegalArgumentException("Cannot convert value to " + type.getName() + ": " + value);
//     }
// 
//     private List<Object> toList(final ActualType elementType, final String value) {
//         final String plainValue = Strings.removeStartAndEndChars(value, '[', ']');
//         if (plainValue.trim().isEmpty()) {
//             return Collections.emptyList();
//         }
//         final String[] parts = parseListValues(plainValue);
//         final List<Object> list = new ArrayList<>(parts.length);
//         for (int i = 0; i < parts.length; i++) {
//             list.add(elementConverter.convert(elementType.rawType(), elementType.genericType(), parts[i].trim()));
//         }
//         return list;
//     }
// 
//     private static <E extends Enum<E>> EnumSet<E> enumSet(final Class<E> enumType, final List<?> list) {
//         final EnumSet<E> set = EnumSet.noneOf(enumType);
//         list.forEach(v -> set.add(enumType.cast(v)));
//         return set;
//     }
// }


import java.util.Collection;
import java.util.List;
import static java.util.Objects.requireNonNull;
import static org.tools4j.spockito.table.GenericTypes.actualTypeForTypeParam;
import static org.tools4j.spockito.table.GenericTypes.genericComponentType;
import org.tools4j.spockito.table.Converters.CollectionConverter;
import org.tools4j.spockito.table.GenericTypes.ActualType;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
        this.valueConverter = requireNonNull(valueConverter);
    }

    public static TableConverter create(final Parameter parameter, final ValueConverter valueConverter) {
        return new SpockitoTableConverter(parameter.getType(), parameter.getParameterizedType(), valueConverter);
    }

    public static TableConverter create(final Field field, final ValueConverter valueConverter) {
        return new SpockitoTableConverter(field.getType(), field.getGenericType(), valueConverter);
    }

    @Override
    public Object convert(final Table table) {
        requireNonNull(table);
        if (targetClass.isInstance(table)) {
            return table;
        }
        final ActualType rowType;
        if (Collection.class.isAssignableFrom(targetClass)) {
            rowType = actualTypeForTypeParam(targetType, 0, 1);
        } else if (targetClass.isArray()) {
            rowType = genericComponentType(targetClass, targetType);
        } else {
            throw new IllegalArgumentException("No known conversion from Table to " + targetType);
        }
        final List<?> rows = table.toList(rowType.rawType(), rowType.genericType(), valueConverter);
        if (List.class.isAssignableFrom(targetClass)) {
            return targetClass.cast(rows);
        }
        if (Collection.class.isAssignableFrom(targetClass)) {
// Path: spockito-table/src/main/java/org/tools4j/spockito/table/Converters.java
// public static class CollectionConverter implements ValueConverter {
//     private final ValueConverter elementConverter;
//     public CollectionConverter(final ValueConverter elementConverter) {
//         this.elementConverter = requireNonNull(elementConverter);
//     }
// 
//     @Override
//     public <T> T convert(final Class<T> type, final Type genericType, final String value) {
//         if (!Collection.class.isAssignableFrom(type)) {
//             throw new IllegalArgumentException("Type must be a collection: " + type.getName());
//         }
//         final ActualType elementType = actualTypeForTypeParam(genericType, 0, 1);
//         final List<?> list = toList(elementType, value);
//         return convert(type, genericType, list, value);
//     }
// 
//     public <T> T convert(final Class<T> type, final Type genericType, final List<?> list) {
//         return convert(type, genericType, list, list);
//     }
// 
//     public <T> T convert(final Class<T> type, final Type genericType, final List<?> list, final Object value) {
//         if (type.isInstance(list)) {
//             return type.cast(list);
//         }
//         if (type.isAssignableFrom(ArrayList.class)) {
//             return type.cast(new ArrayList<>(list));
//         }
//         if (type.isAssignableFrom(Vector.class)) {
//             return type.cast(new Vector<>(list));
//         }
//         if (type.isAssignableFrom(LinkedList.class)) {
//             return type.cast(new LinkedList<>(list));
//         }
//         if (type.isAssignableFrom(ArrayDeque.class)) {
//             return type.cast(new ArrayDeque<>(list));
//         }
//         if (type.isAssignableFrom(LinkedHashSet.class)) {
//             return type.cast(new LinkedHashSet<>(list));
//         }
//         if (type.isAssignableFrom(TreeSet.class)) {
//             return type.cast(new TreeSet<>(list));
//         }
//         if (type.isAssignableFrom(HashSet.class)) {
//             return type.cast(new HashSet<>(list));
//         }
//         if (type.isAssignableFrom(EnumSet.class)) {
//             final ActualType elementType = actualTypeForTypeParam(genericType, 0, 1);
//             final EnumSet<?> enumSet = enumSet(elementType.rawType().asSubclass(Enum.class), list);
//             return type.cast(enumSet);
//         }
//         if (type.isAssignableFrom(ConcurrentLinkedQueue.class)) {
//             return type.cast(new ConcurrentLinkedQueue<>(list));
//         }
//         if (type.isAssignableFrom(ConcurrentLinkedDeque.class)) {
//             return type.cast(new ConcurrentLinkedDeque<>(list));
//         }
//         if (type.isAssignableFrom(ConcurrentSkipListSet.class)) {
//             return type.cast(new ConcurrentSkipListSet<>(list));
//         }
//         //unsupported collection type
//         throw new IllegalArgumentException("Cannot convert value to " + type.getName() + ": " + value);
//     }
// 
//     private List<Object> toList(final ActualType elementType, final String value) {
//         final String plainValue = Strings.removeStartAndEndChars(value, '[', ']');
//         if (plainValue.trim().isEmpty()) {
//             return Collections.emptyList();
//         }
//         final String[] parts = parseListValues(plainValue);
//         final List<Object> list = new ArrayList<>(parts.length);
//         for (int i = 0; i < parts.length; i++) {
//             list.add(elementConverter.convert(elementType.rawType(), elementType.genericType(), parts[i].trim()));
//         }
//         return list;
//     }
// 
//     private static <E extends Enum<E>> EnumSet<E> enumSet(final Class<E> enumType, final List<?> list) {
//         final EnumSet<E> set = EnumSet.noneOf(enumType);
//         list.forEach(v -> set.add(enumType.cast(v)));
//         return set;
//     }
// }


// Path: spockito-table/src/main/java/org/tools4j/spockito/table/SpockitoTableConverter.java
import java.util.Collection;
import java.util.List;
import static java.util.Objects.requireNonNull;
import static org.tools4j.spockito.table.GenericTypes.actualTypeForTypeParam;
import static org.tools4j.spockito.table.GenericTypes.genericComponentType;
import org.tools4j.spockito.table.Converters.CollectionConverter;
import org.tools4j.spockito.table.GenericTypes.ActualType;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;

        this.valueConverter = requireNonNull(valueConverter);
    }

    public static TableConverter create(final Parameter parameter, final ValueConverter valueConverter) {
        return new SpockitoTableConverter(parameter.getType(), parameter.getParameterizedType(), valueConverter);
    }

    public static TableConverter create(final Field field, final ValueConverter valueConverter) {
        return new SpockitoTableConverter(field.getType(), field.getGenericType(), valueConverter);
    }

    @Override
    public Object convert(final Table table) {
        requireNonNull(table);
        if (targetClass.isInstance(table)) {
            return table;
        }
        final ActualType rowType;
        if (Collection.class.isAssignableFrom(targetClass)) {
            rowType = actualTypeForTypeParam(targetType, 0, 1);
        } else if (targetClass.isArray()) {
            rowType = genericComponentType(targetClass, targetType);
        } else {
            throw new IllegalArgumentException("No known conversion from Table to " + targetType);
        }
        final List<?> rows = table.toList(rowType.rawType(), rowType.genericType(), valueConverter);
        if (List.class.isAssignableFrom(targetClass)) {
            return targetClass.cast(rows);
        }
        if (Collection.class.isAssignableFrom(targetClass)) {
            return new CollectionConverter(valueConverter).convert(targetClass, targetType, rows);