class PositionalParameterTypes extends ParameterTypes {

    @Override
    public List<Pair<ParameterTypes, ParameterConversions>> candidates() {
        Set<Pair<ParameterTypes, ParameterConversions>> result = new LinkedHashSet<>();
        int n = types.size();
        int m = ConversionKind.values().length;
        int[] conversionMap = init(n);
        conversionMap = next(conversionMap, n, m);
        while (conversionMap != null) {
            // Calculate new types and conversions
            List<Type> newTypes = new ArrayList<>();
            PositionalParameterConversions conversions = new PositionalParameterConversions();

            // For every possible conversion sequence
            boolean different = false;
            for (int i = 0; i < n; i++) {
                // Compute new type and conversion
                ConversionKind kind = ConversionKind.values()[conversionMap[i]];
                Type type = types.get(i);
                Type newType = type;
                Conversion conversion = new Conversion(NONE, newType);
                if (kind == LIST_TO_ELEMENT) {
                    if (type instanceof ListType) {
                        newType = ((ListType) type).getElementType();
                        conversion = new Conversion(kind, newType);

                        different = true;
                    }
                }
                newTypes.add(newType);
                conversions.add(conversion);
            }

            // Add new candidate
            if (different) {
                PositionalParameterTypes newSignature = new PositionalParameterTypes(newTypes);
                result.add(new Pair<>(newSignature, conversions));
            }

            // Next sequence
            conversionMap = next(conversionMap, n, m);
        }
        return new ArrayList<>(result);
    }

    public  PositionalParameterTypes(List<Type> types);

}