/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package freemarker.ext.beans;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import freemarker.core.BugException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.Version;
import freemarker.template.utility.ClassUtil;

/**
 * The argument types of a method call; usable as cache key.
 */
final class ArgumentTypes {
    
    /**
     * Conversion difficulty: Lowest; Java Reflection will do it automatically.
     */
    private static final int CONVERSION_DIFFICULTY_REFLECTION = 0;

    /**
     * Conversion difficulty: Java reflection API will won't convert it, FreeMarker has to do it.
     */
    private static final int CONVERSION_DIFFICULTY_FREEMARKER = 1;
    
    /**
     * Conversion difficulty: Highest; conversion is not possible.
     */
    private static final int CONVERSION_DIFFICULTY_IMPOSSIBLE = 2;

    /**
     * The types of the arguments; for varags this contains the exploded list (not the array). 
     */
    private final Class<?>[] types;
    
    private final boolean bugfixed;
    
    /**
     * @param args The actual arguments. A varargs argument should be present exploded, no as an array.
     * @param bugfixed Introduced in 2.3.21, sets this object to a mode that works well with {@link BeansWrapper}-s
     *      created with {@link Version} 2.3.21 or higher.
     */
    ArgumentTypes(Object[] args, boolean bugfixed) {
        int ln = args.length;
        Class<?>[] typesTmp = new Class[ln];
        for (int i = 0; i < ln; ++i) {
            Object arg = args[i];
            typesTmp[i] = arg == null
                    ? (bugfixed ? Null.class : Object.class)
                    : arg.getClass();
        }
        
        // `typesTmp` is used so the array is only modified before it's stored in the final `types` field (see JSR-133)
        types = typesTmp;  
        this.bugfixed = bugfixed;
    }
    
    @Override
    public int hashCode() {
        int hash = 0;
        for (int i = 0; i < types.length; ++i) {
            hash ^= types[i].hashCode();
        }
        return hash;
    }
    
    @Override
    public boolean equals(Object o) {
        if (o instanceof ArgumentTypes) {
            ArgumentTypes cs = (ArgumentTypes) o;
            if (cs.types.length != types.length) {
                return false;
            }
            for (int i = 0; i < types.length; ++i) {
                if (cs.types[i] != types[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    
    /**
     * @return Possibly {@link EmptyCallableMemberDescriptor#NO_SUCH_METHOD} or
     *         {@link EmptyCallableMemberDescriptor#AMBIGUOUS_METHOD}. 
     */
    MaybeEmptyCallableMemberDescriptor getMostSpecific(
            List<ReflectionCallableMemberDescriptor> memberDescs, boolean varArg) {
        LinkedList<CallableMemberDescriptor> applicables = getApplicables(memberDescs, varArg);
        if (applicables.isEmpty()) {
            return EmptyCallableMemberDescriptor.NO_SUCH_METHOD;
        }
        if (applicables.size() == 1) {
            return applicables.getFirst();
        }
        
        LinkedList<CallableMemberDescriptor> maximals = new LinkedList<>();
        for (CallableMemberDescriptor applicable : applicables) {
            boolean lessSpecific = false;
            for (Iterator<CallableMemberDescriptor> maximalsIter = maximals.iterator(); 
                maximalsIter.hasNext(); ) {
                CallableMemberDescriptor maximal = maximalsIter.next();
                final int cmpRes = compareParameterListPreferability(
                        applicable.getParamTypes(), maximal.getParamTypes(), varArg); 
                if (cmpRes > 0) {
                    maximalsIter.remove();
                } else if (cmpRes < 0) {
                    lessSpecific = true;
                }
            }
            if (!lessSpecific) {
                maximals.addLast(applicable);
            }
        }
        if (maximals.size() > 1) {
            return EmptyCallableMemberDescriptor.AMBIGUOUS_METHOD;
        }
        return maximals.getFirst();
    }

    /**
     * Tells if among the parameter list of two methods, which one fits this argument list better.
     * This method assumes that the parameter lists are applicable to this argument lists; if that's not ensured,
     * what the result will be is undefined.
     * 
     * <p>This method behaves differently in {@code bugfixed}-mode (used when a {@link BeansWrapper} is created with
     * incompatible improvements set to 2.3.21 or higher). Below we describe the bugfixed behavior only. 
     *  
     * <p>The decision is made by comparing the preferability of each parameter types of the same position in a loop.
     * At the end, the parameter list with the more preferred parameters will be the preferred one. If both parameter
     * lists has the same amount of preferred parameters, the one that has the first (lower index) preferred parameter
     * is the preferred one. Otherwise the two parameter list are considered to be equal in terms of preferability.
     * 
     * <p>If there's no numerical conversion involved, the preferability of two parameter types is decided on how
     * specific their types are. For example, {@code String} is more specific than {@link Object} (because
     * {@code Object.class.isAssignableFrom(String.class)}-s), and so {@code String} is preferred. Primitive
     * types are considered to be more specific than the corresponding boxing class (like {@code boolean} is more
     * specific than {@code Boolean}, because the former can't store {@code null}). The preferability decision gets
     * trickier when there's a possibility of numerical conversion from the actual argument type to the type of some of
     * the parameters. If such conversion is only possible for one of the competing parameter types, that parameter
     * automatically wins. If it's possible for both, {@link OverloadedNumberUtil#getArgumentConversionPrice} will
     * be used to calculate the conversion "price", and the parameter type with lowest price wins. There are also
     * a twist with array-to-list and list-to-array conversions; we try to avoid those, so the parameter where such
     * conversion isn't needed will always win.
     * 
     * @param paramTypes1 The parameter types of one of the competing methods
     * @param paramTypes2 The parameter types of the other competing method
     * @param varArg Whether these competing methods are varargs methods. 
     * @return More than 0 if the first parameter list is preferred, less then 0 if the other is preferred,
     *        0 if there's no decision 
     */
    int compareParameterListPreferability(Class<?>[] paramTypes1, Class<?>[] paramTypes2, boolean varArg) {
        final int argTypesLen = types.length; 
        final int paramTypes1Len = paramTypes1.length;
        final int paramTypes2Len = paramTypes2.length;
        //assert varArg || paramTypes1Len == paramTypes2Len;
        
        if (bugfixed) {
            int paramList1WeakWinCnt = 0;
            int paramList2WeakWinCnt = 0;
            int paramList1WinCnt = 0;
            int paramList2WinCnt = 0;
            int paramList1StrongWinCnt = 0;
            int paramList2StrongWinCnt = 0;
            int paramList1VeryStrongWinCnt = 0;
            int paramList2VeryStrongWinCnt = 0;
            int firstWinerParamList = 0;
            for (int i = 0; i < argTypesLen; i++) {
                final Class<?> paramType1 = getParamType(paramTypes1, paramTypes1Len, i, varArg);
                final Class<?> paramType2 = getParamType(paramTypes2, paramTypes2Len, i, varArg);
                
                final int winerParam;  // 1 => paramType1; -1 => paramType2; 0 => draw
                if (paramType1 == paramType2) {
                    winerParam = 0;
                } else {
                    final Class<?> argType = types[i];
                    final boolean argIsNum = Number.class.isAssignableFrom(argType);
                    
                    final int numConvPrice1;
                    if (argIsNum && ClassUtil.isNumerical(paramType1)) {
                        final Class<?> nonPrimParamType1 = paramType1.isPrimitive()
                                ? ClassUtil.primitiveClassToBoxingClass(paramType1) : paramType1; 
                        numConvPrice1 = OverloadedNumberUtil.getArgumentConversionPrice(argType, nonPrimParamType1);
                    } else {
                        numConvPrice1 = Integer.MAX_VALUE;
                    }
                    // numConvPrice1 is Integer.MAX_VALUE if either:
                    // - argType and paramType1 aren't both numerical
                    // - FM doesn't know some of the numerical types, or the conversion between them is not allowed    
                    
                    final int numConvPrice2;
                    if (argIsNum && ClassUtil.isNumerical(paramType2)) {
                        final Class<?> nonPrimParamType2 = paramType2.isPrimitive()
                                ? ClassUtil.primitiveClassToBoxingClass(paramType2) : paramType2; 
                        numConvPrice2 = OverloadedNumberUtil.getArgumentConversionPrice(argType, nonPrimParamType2);
                    } else {
                        numConvPrice2 = Integer.MAX_VALUE;
                    }
                    
                    if (numConvPrice1 == Integer.MAX_VALUE) {
                        if (numConvPrice2 == Integer.MAX_VALUE) {  // No numerical conversions anywhere
                            // List to array conversions (unwrapping sometimes makes a List instead of an array)
                            if (List.class.isAssignableFrom(argType)
                                    && (paramType1.isArray() || paramType2.isArray())) {
                                if (paramType1.isArray()) {
                                    if (paramType2.isArray()) {  // both paramType1 and paramType2 are arrays
                                        int r = compareParameterListPreferability_cmpTypeSpecificty(
                                                paramType1.getComponentType(), paramType2.getComponentType());
                                        // Because we don't know if the List items are instances of the component
                                        // type or not, we prefer the safer choice, which is the more generic array:
                                        if (r > 0) {
                                            winerParam = 2;
                                            paramList2StrongWinCnt++;
                                        } else if (r < 0) {
                                            winerParam = 1;
                                            paramList1StrongWinCnt++;
                                        } else {
                                            winerParam = 0;
                                        }
                                    } else {  // paramType1 is array, paramType2 isn't
                                        // Avoid List to array conversion if the other way makes any sense:
                                        if (Collection.class.isAssignableFrom(paramType2)) {
                                            winerParam = 2;
                                            paramList2StrongWinCnt++;
                                        } else {
                                            winerParam = 1;
                                            paramList1WeakWinCnt++;
                                        }
                                    }
                                } else {  // paramType2 is array, paramType1 isn't
                                    // Avoid List to array conversion if the other way makes any sense:
                                    if (Collection.class.isAssignableFrom(paramType1)) {
                                        winerParam = 1;
                                        paramList1StrongWinCnt++;
                                    } else {
                                        winerParam = 2;
                                        paramList2WeakWinCnt++;
                                    }
                                }
                            } else if (argType.isArray()
                                    && (List.class.isAssignableFrom(paramType1)
                                            || List.class.isAssignableFrom(paramType2))) {
                                // Array to List conversions (unwrapping sometimes makes an array instead of a List)
                                if (List.class.isAssignableFrom(paramType1)) {
                                    if (List.class.isAssignableFrom(paramType2)) {
                                        // Both paramType1 and paramType2 extends List
                                        winerParam = 0;
                                    } else {
                                        // Only paramType1 extends List
                                        winerParam = 2;
                                        paramList2VeryStrongWinCnt++;
                                    }
                                } else {
                                    // Only paramType2 extends List
                                    winerParam = 1;
                                    paramList1VeryStrongWinCnt++;
                                }
                            } else {  // No list to/from array conversion
                                final int r = compareParameterListPreferability_cmpTypeSpecificty(
                                        paramType1, paramType2);
                                if (r > 0) {
                                    winerParam = 1;
                                    if (r > 1) {
                                        paramList1WinCnt++;
                                    } else {
                                        paramList1WeakWinCnt++;
                                    }
                                } else if (r < 0) {
                                    winerParam = -1;
                                    if (r < -1) {
                                        paramList2WinCnt++;
                                    } else {
                                        paramList2WeakWinCnt++;
                                    }
                                } else {
                                    winerParam = 0;
                                }
                            }
                        } else {  // No num. conv. of param1, num. conv. of param2
                            winerParam = -1;
                            paramList2WinCnt++;
                        }
                    } else if (numConvPrice2 == Integer.MAX_VALUE) {  // Num. conv. of param1, not of param2
                        winerParam = 1;
                        paramList1WinCnt++;
                    } else {  // Num. conv. of both param1 and param2
                        if (numConvPrice1 != numConvPrice2) {
                            if (numConvPrice1 < numConvPrice2) {
                                winerParam = 1;
                                if (numConvPrice1 < OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE
                                        && numConvPrice2 > OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE) {
                                    paramList1StrongWinCnt++;
                                } else {
                                    paramList1WinCnt++;
                                }
                            } else {
                                winerParam = -1;
                                if (numConvPrice2 < OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE
                                        && numConvPrice1 > OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE) {
                                    paramList2StrongWinCnt++;
                                } else {
                                    paramList2WinCnt++;
                                }
                            }
                        } else {
                            winerParam = (paramType1.isPrimitive() ? 1 : 0) - (paramType2.isPrimitive() ? 1 : 0);
                            if (winerParam == 1) paramList1WeakWinCnt++;
                            else if (winerParam == -1) paramList2WeakWinCnt++;
                        }
                    }
                }  // when paramType1 != paramType2
                
                if (firstWinerParamList == 0 && winerParam != 0) {
                    firstWinerParamList = winerParam; 
                }
            }  // for each parameter types
            
            if (paramList1VeryStrongWinCnt != paramList2VeryStrongWinCnt) {
                return paramList1VeryStrongWinCnt - paramList2VeryStrongWinCnt;
            } else if (paramList1StrongWinCnt != paramList2StrongWinCnt) {
                return paramList1StrongWinCnt - paramList2StrongWinCnt;
            } else if (paramList1WinCnt != paramList2WinCnt) {
                return paramList1WinCnt - paramList2WinCnt;
            } else if (paramList1WeakWinCnt != paramList2WeakWinCnt) {
                return paramList1WeakWinCnt - paramList2WeakWinCnt;
            } else if (firstWinerParamList != 0) {  // paramList1WinCnt == paramList2WinCnt
                return firstWinerParamList;
            } else { // still undecided
                if (varArg) {
                    if (paramTypes1Len == paramTypes2Len) {
                        // If we had a 0-length varargs array in both methods, we also compare the types at the
                        // index of the varargs parameter, like if we had a single varargs argument. However, this
                        // time we don't have an argument type, so we can only decide based on type specificity:
                        if (argTypesLen == paramTypes1Len - 1) {
                            Class<?> paramType1 = getParamType(paramTypes1, paramTypes1Len, argTypesLen, true);
                            Class<?> paramType2 = getParamType(paramTypes2, paramTypes2Len, argTypesLen, true);
                            if (ClassUtil.isNumerical(paramType1) && ClassUtil.isNumerical(paramType2)) {
                                int r = OverloadedNumberUtil.compareNumberTypeSpecificity(paramType1, paramType2);
                                if (r != 0) return r;
                                // falls through
                            }
                            return compareParameterListPreferability_cmpTypeSpecificty(paramType1, paramType2);
                        } else {
                            return 0;
                        }
                    } else {
                        // The method with more fixed parameters wins:
                        return paramTypes1Len - paramTypes2Len;
                    }
                } else {
                    return 0;
                }
            }
        } else { // non-bugfixed (backward-compatible) mode
            boolean paramTypes1HasAMoreSpecific = false;
            boolean paramTypes2HasAMoreSpecific = false;
            for (int i = 0; i < paramTypes1Len; ++i) {
                Class<?> paramType1 = getParamType(paramTypes1, paramTypes1Len, i, varArg);
                Class<?> paramType2 = getParamType(paramTypes2, paramTypes2Len, i, varArg);
                if (paramType1 != paramType2) {
                    paramTypes1HasAMoreSpecific = 
                        paramTypes1HasAMoreSpecific
                        || _MethodUtil.isMoreOrSameSpecificParameterType(paramType1, paramType2, false, 0) != 0;
                    paramTypes2HasAMoreSpecific = 
                        paramTypes2HasAMoreSpecific
                        || _MethodUtil.isMoreOrSameSpecificParameterType(paramType2, paramType1, false, 0) != 0;
                }
            }
            
            if (paramTypes1HasAMoreSpecific) {
                return paramTypes2HasAMoreSpecific ? 0 : 1;
            } else if (paramTypes2HasAMoreSpecific) {
                return -1;
            } else {
                return 0;
            }
        }
    }
    
    /**
     * Trivial comparison of type specificities; unaware of numerical conversions. 
     * 
     * @return Less-than-0, 0, or more-than-0 depending on which side is more specific. The absolute value is 1 if
     *     the difference is only in primitive VS non-primitive, more otherwise.
     */
    private int compareParameterListPreferability_cmpTypeSpecificty(
            final Class<?> paramType1, final Class<?> paramType2) {
        // The more specific (smaller) type wins.
        
        final Class<?> nonPrimParamType1 = paramType1.isPrimitive()
                ? ClassUtil.primitiveClassToBoxingClass(paramType1) : paramType1; 
        final Class<?> nonPrimParamType2 = paramType2.isPrimitive()
                ? ClassUtil.primitiveClassToBoxingClass(paramType2) : paramType2;
                
        if (nonPrimParamType1 == nonPrimParamType2) {
            if (nonPrimParamType1 != paramType1) {
                if (nonPrimParamType2 != paramType2) {
                    return 0;  // identical prim. types; shouldn't ever be reached
                } else {
                    return 1;  // param1 is prim., param2 is non prim.
                }
            } else if (nonPrimParamType2 != paramType2) {
                return -1;  // param1 is non-prim., param2 is prim.
            } else {
                return 0;  // identical non-prim. types
            }
        } else if (nonPrimParamType2.isAssignableFrom(nonPrimParamType1)) {
            return 2;
        } else if (nonPrimParamType1.isAssignableFrom(nonPrimParamType2)) {
            return -2;
        } if (nonPrimParamType1 == Character.class && nonPrimParamType2.isAssignableFrom(String.class)) {
            return 2;  // A character is a 1 long string in FTL, so we pretend that it's a String subtype.
        } if (nonPrimParamType2 == Character.class && nonPrimParamType1.isAssignableFrom(String.class)) {
            return -2;
        } else {
            return 0;  // unrelated types
        }
    }

    private static Class<?> getParamType(Class<?>[] paramTypes, int paramTypesLen, int i, boolean varArg) {
        return varArg && i >= paramTypesLen - 1
                ? paramTypes[paramTypesLen - 1].getComponentType()
                : paramTypes[i];
    }
    
    /**
     * Returns all methods that are applicable to actual
     * parameter types represented by this ArgumentTypes object.
     */
    LinkedList<CallableMemberDescriptor> getApplicables(
            List<ReflectionCallableMemberDescriptor> memberDescs, boolean varArg) {
        LinkedList<CallableMemberDescriptor> applicables = new LinkedList<>();
        for (ReflectionCallableMemberDescriptor memberDesc : memberDescs) {
            int difficulty = isApplicable(memberDesc, varArg);
            if (difficulty != CONVERSION_DIFFICULTY_IMPOSSIBLE) {
                if (difficulty == CONVERSION_DIFFICULTY_REFLECTION) {
                    applicables.add(memberDesc);
                } else if (difficulty == CONVERSION_DIFFICULTY_FREEMARKER) {
                    applicables.add(new SpecialConversionCallableMemberDescriptor(memberDesc));
                } else {
                    throw new BugException();
                }
            }
        }
        return applicables;
    }
    
    /**
     * Returns if the supplied method is applicable to actual
     * parameter types represented by this ArgumentTypes object, also tells
     * how difficult that conversion is.
     * 
     * @return One of the {@code CONVERSION_DIFFICULTY_...} constants.
     */
    private int isApplicable(ReflectionCallableMemberDescriptor memberDesc, boolean varArg) {
        final Class<?>[] paramTypes = memberDesc.getParamTypes(); 
        final int cl = types.length;
        final int fl = paramTypes.length - (varArg ? 1 : 0);
        if (varArg) {
            if (cl < fl) {
                return CONVERSION_DIFFICULTY_IMPOSSIBLE;
            }
        } else {
            if (cl != fl) {
                return CONVERSION_DIFFICULTY_IMPOSSIBLE;
            }
        }
        
        int maxDifficulty = 0;
        for (int i = 0; i < fl; ++i) {
            int difficulty = isMethodInvocationConvertible(paramTypes[i], types[i]);
            if (difficulty == CONVERSION_DIFFICULTY_IMPOSSIBLE) {
                return CONVERSION_DIFFICULTY_IMPOSSIBLE;
            }
            if (maxDifficulty < difficulty) {
                maxDifficulty = difficulty;
            }
        }
        if (varArg) {
            Class<?> varArgParamType = paramTypes[fl].getComponentType();
            for (int i = fl; i < cl; ++i) {
                int difficulty = isMethodInvocationConvertible(varArgParamType, types[i]); 
                if (difficulty == CONVERSION_DIFFICULTY_IMPOSSIBLE) {
                    return CONVERSION_DIFFICULTY_IMPOSSIBLE;
                }
                if (maxDifficulty < difficulty) {
                    maxDifficulty = difficulty;
                }
            }
        }
        return maxDifficulty;
    }

    /**
     * Determines whether a type is convertible to another type via 
     * method invocation conversion, and if so, what kind of conversion is needed.
     * It treates the object type counterpart of primitive types as if they were the primitive types
     * (that is, a Boolean actual parameter type matches boolean primitive formal type). This behavior
     * is because this method is used to determine applicable methods for 
     * an actual parameter list, and primitive types are represented by 
     * their object duals in reflective method calls.
     * @param formal the parameter type to which the actual 
     * parameter type should be convertible; possibly a primitive type
     * @param actual the argument type; not a primitive type, maybe {@link Null}.
     * 
     * @return One of the {@code CONVERSION_DIFFICULTY_...} constants.
     */
    private int isMethodInvocationConvertible(final Class<?> formal, final Class<?> actual) {
        // Check for identity or widening reference conversion
        if (formal.isAssignableFrom(actual) && actual != CharacterOrString.class) {
            return CONVERSION_DIFFICULTY_REFLECTION;
        } else if (bugfixed) {
            final Class<?> formalNP;
            if (formal.isPrimitive()) {
                if (actual == Null.class) {
                    return CONVERSION_DIFFICULTY_IMPOSSIBLE;
                }
                
                formalNP = ClassUtil.primitiveClassToBoxingClass(formal);
                if (actual == formalNP) {
                    // Character and char, etc.
                    return CONVERSION_DIFFICULTY_REFLECTION;
                }
            } else {  // formal is non-primitive
                if (actual == Null.class) {
                    return CONVERSION_DIFFICULTY_REFLECTION;
                }
                
                formalNP = formal;
            }
            if (Number.class.isAssignableFrom(actual) && Number.class.isAssignableFrom(formalNP)) {
                return OverloadedNumberUtil.getArgumentConversionPrice(actual, formalNP) == Integer.MAX_VALUE
                        ? CONVERSION_DIFFICULTY_IMPOSSIBLE : CONVERSION_DIFFICULTY_REFLECTION;
            } else if (formal.isArray()) {
                // BeansWrapper method/constructor calls convert from List to array automatically
                return List.class.isAssignableFrom(actual)
                        ? CONVERSION_DIFFICULTY_FREEMARKER : CONVERSION_DIFFICULTY_IMPOSSIBLE;
            } else if (actual.isArray() && formal.isAssignableFrom(List.class)) {
                // BeansWrapper method/constructor calls convert from array to List automatically
                return CONVERSION_DIFFICULTY_FREEMARKER;
            } else if (actual == CharacterOrString.class
                    && (formal.isAssignableFrom(String.class)
                            || formal.isAssignableFrom(Character.class) || formal == char.class)) {
                return CONVERSION_DIFFICULTY_FREEMARKER;
            } else {
                return CONVERSION_DIFFICULTY_IMPOSSIBLE;
            }
        } else { // if !bugfixed
            // This non-bugfixed (backward-compatible, pre-2.3.21) branch:
            // - Doesn't convert *to* non-primitive numerical types (unless the argument is a BigDecimal).
            //   (This is like in Java language, which also doesn't coerce to non-primitive numerical types.) 
            // - Doesn't support BigInteger conversions
            // - Doesn't support NumberWithFallbackType-s and CharacterOrString-s. Those are only produced in bugfixed
            //   mode anyway.
            // - Doesn't support conversion between array and List
            if (formal.isPrimitive()) {
                // Check for boxing with widening primitive conversion. Note that 
                // actual parameters are never primitives.
                // It doesn't do the same with boxing types... that was a bug.
                if (formal == Boolean.TYPE) {
                    return actual == Boolean.class
                            ? CONVERSION_DIFFICULTY_REFLECTION : CONVERSION_DIFFICULTY_IMPOSSIBLE;
                } else if (formal == Double.TYPE && 
                        (actual == Double.class || actual == Float.class || 
                         actual == Long.class || actual == Integer.class || 
                         actual == Short.class || actual == Byte.class)) {
                     return CONVERSION_DIFFICULTY_REFLECTION;
                } else if (formal == Integer.TYPE && 
                        (actual == Integer.class || actual == Short.class || 
                         actual == Byte.class)) {
                     return CONVERSION_DIFFICULTY_REFLECTION;
                } else if (formal == Long.TYPE && 
                        (actual == Long.class || actual == Integer.class || 
                         actual == Short.class || actual == Byte.class)) {
                     return CONVERSION_DIFFICULTY_REFLECTION;
                } else if (formal == Float.TYPE && 
                        (actual == Float.class || actual == Long.class || 
                         actual == Integer.class || actual == Short.class || 
                         actual == Byte.class)) {
                     return CONVERSION_DIFFICULTY_REFLECTION;
                } else if (formal == Character.TYPE) {
                    return actual == Character.class
                            ? CONVERSION_DIFFICULTY_REFLECTION : CONVERSION_DIFFICULTY_IMPOSSIBLE;
                } else if (formal == Byte.TYPE && actual == Byte.class) {
                    return CONVERSION_DIFFICULTY_REFLECTION;
                } else if (formal == Short.TYPE &&
                   (actual == Short.class || actual == Byte.class)) {
                    return CONVERSION_DIFFICULTY_REFLECTION;
                } else if (BigDecimal.class.isAssignableFrom(actual) && ClassUtil.isNumerical(formal)) {
                    // Special case for BigDecimals as we deem BigDecimal to be
                    // convertible to any numeric type - either object or primitive.
                    // This can actually cause us trouble as this is a narrowing 
                    // conversion, not widening. 
                    return CONVERSION_DIFFICULTY_REFLECTION;
                } else {
                    return CONVERSION_DIFFICULTY_IMPOSSIBLE;
                }
            } else {
                return CONVERSION_DIFFICULTY_IMPOSSIBLE;
            }
        }
    }
    
    /**
     * Symbolizes the class of null (it's missing from Java).
     */
    private static class Null {
        
        // Can't be instantiated
        private Null() { }
        
    }
    
    /**
     * Used instead of {@link ReflectionCallableMemberDescriptor} when the method is only applicable
     * ({@link #isApplicable}) with conversion that Java reflection won't do. It delegates to a
     * {@link ReflectionCallableMemberDescriptor}, but it adds the necessary conversions to the invocation methods. 
     */
    private static final class SpecialConversionCallableMemberDescriptor extends CallableMemberDescriptor {
        
        private final ReflectionCallableMemberDescriptor callableMemberDesc;

        SpecialConversionCallableMemberDescriptor(ReflectionCallableMemberDescriptor callableMemberDesc) {
            this.callableMemberDesc = callableMemberDesc;
        }

        @Override
        TemplateModel invokeMethod(BeansWrapper bw, Object obj, Object[] args) throws TemplateModelException,
                InvocationTargetException, IllegalAccessException {
            convertArgsToReflectionCompatible(bw, args);
            return callableMemberDesc.invokeMethod(bw, obj, args);
        }

        @Override
        Object invokeConstructor(BeansWrapper bw, Object[] args) throws IllegalArgumentException,
                InstantiationException, IllegalAccessException, InvocationTargetException, TemplateModelException {
            convertArgsToReflectionCompatible(bw, args);
            return callableMemberDesc.invokeConstructor(bw, args);
        }

        @Override
        String getDeclaration() {
            return callableMemberDesc.getDeclaration();
        }

        @Override
        boolean isConstructor() {
            return callableMemberDesc.isConstructor();
        }

        @Override
        boolean isStatic() {
            return callableMemberDesc.isStatic();
        }

        @Override
        boolean isVarargs() {
            return callableMemberDesc.isVarargs();
        }

        @Override
        Class<?>[] getParamTypes() {
            return callableMemberDesc.getParamTypes();
        }
        
        @Override
        String getName() {
            return callableMemberDesc.getName();
        }

        private void convertArgsToReflectionCompatible(BeansWrapper bw, Object[] args) throws TemplateModelException {
            Class<?>[] paramTypes = callableMemberDesc.getParamTypes();
            int ln = paramTypes.length;
            for (int i = 0; i < ln; i++) {
                Class<?> paramType = paramTypes[i];
                final Object arg = args[i];
                if (arg == null) continue;
                
                // Handle conversion between List and array types, in both directions. Java reflection won't do such
                // conversion, so we have to.
                // Most reflection-incompatible conversions were already addressed by the unwrapping. The reason
                // this one isn't is that for overloaded methods the hint of a given parameter position is often vague,
                // so we may end up with a List even if some parameter types at that position are arrays (remember, we
                // have to chose one unwrapping target type, despite that we have many possible overloaded methods), or
                // the other way around (that happens when AdapterTemplateMoldel returns an array).
                // Later, the overloaded method selection will assume that a List argument is applicable to an array
                // parameter, and that an array argument is applicable to a List parameter, so we end up with this
                // situation.
                if (paramType.isArray() && arg instanceof List) {
                   args[i] = bw.listToArray((List<?>) arg, paramType, null);
                }
                if (arg.getClass().isArray() && paramType.isAssignableFrom(List.class)) {
                    args[i] = bw.arrayToList(arg);
                }
                
                // Handle the conversion from CharacterOrString to Character or String:
                if (arg instanceof CharacterOrString) {
                    if (paramType == Character.class || paramType == char.class
                            || (!paramType.isAssignableFrom(String.class)
                                    && paramType.isAssignableFrom(Character.class))) {
                        args[i] = Character.valueOf(((CharacterOrString) arg).getAsChar());
                    } else {
                        args[i] = ((CharacterOrString) arg).getAsString();
                    }
                }
            }
        }

    }
    
}