base/common/src/main/com/thesett/common/util/TypeConverter.java
public static Class bestMatchingConversion(MultiTypeData d, Collection<Class> types)
    {
        /*log.fine("public static Class bestMatchingConvertion(MultiTypeData d, Set<Class> types): called");*/
        /*log.fine("d = " + d);*/
        /*log.fine("types = " + types);*/

        // Try to match the native type first before trying the convertions.
        switch (d.nativeType)
        {
        case OBJECT:
        {
            // Check if the matching Object class can be found in the set of possible classes.
            if (types.contains(d.objectValue.getClass()))
            {
                return d.objectValue.getClass();
            }

            break;
        }

        case BOOLEAN:
        {
            // Check if boolean is in the set of possible classes to match.
            if (types.contains(boolean.class))
            {
                return boolean.class;
            }
            else if (types.contains(Boolean.class))
            {
                return Boolean.class;
            }

            break;
        }

        case CHAR:
        {
            // Check if char is in the set of possible classes to match.
            if (types.contains(char.class))
            {
                return char.class;
            }
            else if (types.contains(Character.class))
            {
                return Character.class;
            }

            break;
        }

        case BYTE:
        {
            // Check if byte is in the set of possible classes to match.
            if (types.contains(byte.class))
            {
                return byte.class;
            }
            else if (types.contains(Byte.class))
            {
                return Byte.class;
            }

            break;
        }

        case SHORT:
        {
            // Check if short is in the set of possible classes to match.
            if (types.contains(short.class))
            {
                return short.class;
            }
            else if (types.contains(Short.class))
            {
                return Short.class;
            }

            break;
        }

        case INT:
        {
            // Check if int is in the set of possible classes to match.
            if (types.contains(int.class))
            {
                return int.class;
            }
            else if (types.contains(Integer.class))
            {
                return Integer.class;
            }

            break;
        }

        case LONG:
        {
            // Check if long is in the set of possible classes to match.
            if (types.contains(long.class))
            {
                return long.class;
            }
            else if (types.contains(Long.class))
            {
                return Long.class;
            }

            break;
        }

        case FLOAT:
        {
            // Check if float is in the set of possible classes to match.
            if (types.contains(float.class))
            {
                return float.class;
            }
            else if (types.contains(Float.class))
            {
                return Float.class;
            }

            break;
        }

        case DOUBLE:
        {
            // Check if double is in the set of possible classes to match.
            if (types.contains(double.class))
            {
                return double.class;
            }
            else if (types.contains(Double.class))
            {
                return Double.class;
            }

            break;
        }

        case STRING:
        {
            // Check if String is in the set of possible classes to match.
            if (types.contains(String.class))
            {
                return String.class;
            }

            break;
        }

        default:
        {
            throw new IllegalStateException("Unknown MultiTypeData type.");
        }
        }

        // Check if the multi type can be converted to a boolean and boolean is in the set of possible convertions.
        if (((d.typeFlags & BOOLEAN) != 0) && types.contains(boolean.class))
        {
            return boolean.class;
        }
        else if (((d.typeFlags & BOOLEAN) != 0) && types.contains(Boolean.class))
        {
            return Boolean.class;
        }

        // Check if the multi type can be converted to a byte and byte is in the set of possible convertions.
        else if (((d.typeFlags & BYTE) != 0) && types.contains(byte.class))
        {
            return byte.class;
        }
        else if (((d.typeFlags & BYTE) != 0) && types.contains(Byte.class))
        {
            return Byte.class;
        }

        // Check if the multi type can be converted to a char and char is in the set of possible convertions.
        else if (((d.typeFlags & CHAR) != 0) && types.contains(char.class))
        {
            return char.class;
        }
        else if (((d.typeFlags & CHAR) != 0) && types.contains(Character.class))
        {
            return Character.class;
        }

        // Check if the multi type can be converted to a short and short is in the set of possible convertions.
        else if (((d.typeFlags & SHORT) != 0) && types.contains(short.class))
        {
            return short.class;
        }
        else if (((d.typeFlags & SHORT) != 0) && types.contains(Short.class))
        {
            return Short.class;
        }

        // Check if the multi type can be converted to a int and int is in the set of possible convertions.
        else if (((d.typeFlags & INT) != 0) && types.contains(int.class))
        {
            return int.class;
        }
        else if (((d.typeFlags & INT) != 0) && types.contains(Integer.class))
        {
            return Integer.class;
        }

        // Check if the multi type can be converted to a long and long is in the set of possible convertions.
        else if (((d.typeFlags & LONG) != 0) && types.contains(long.class))
        {
            return long.class;
        }
        else if (((d.typeFlags & LONG) != 0) && types.contains(Long.class))
        {
            return Long.class;
        }

        // Check if the multi type can be converted to a float and float is in the set of possible convertions.
        else if (((d.typeFlags & FLOAT) != 0) && types.contains(float.class))
        {
            return float.class;
        }
        else if (((d.typeFlags & FLOAT) != 0) && types.contains(Float.class))
        {
            return Float.class;
        }

        // Check if the multi type can be converted to a double and double is in the set of possible convertions.
        else if (((d.typeFlags & DOUBLE) != 0) && types.contains(double.class))
        {
            return double.class;
        }
        else if (((d.typeFlags & DOUBLE) != 0) && types.contains(Double.class))
        {
            return Double.class;
        }

        // Check if the multi type can be converted to a String and String is in the set of possible convertions.
        else if (((d.typeFlags & STRING) != 0) && types.contains(String.class))
        {
            return String.class;
        }

        // No matching type convertion found so return null.
        else
        {
            return null;
        }
    }
public static Class bestMatchingConversion(MultiTypeData d, Collection<Class> types)
    {
        /*log.fine("public static Class bestMatchingConvertion(MultiTypeData d, Set<Class> types): called");*/
        /*log.fine("d = " + d);*/
        /*log.fine("types = " + types);*/

        // Try to match the native type first before trying the convertions.
        switch (d.nativeType)
        {
        case OBJECT:
        {
            // Check if the matching Object class can be found in the set of possible classes.
            if (types.contains(d.objectValue.getClass()))
            {
                return d.objectValue.getClass();
            }

            break;
        }

        case BOOLEAN:
        {
            // Check if boolean is in the set of possible classes to match.
            if (types.contains(boolean.class))
            {
                return boolean.class;
            }
            else if (types.contains(Boolean.class))
            {
                return Boolean.class;
            }

            break;
        }

        case CHAR:
        {
            // Check if char is in the set of possible classes to match.
            if (types.contains(char.class))
            {
                return char.class;
            }
            else if (types.contains(Character.class))
            {
                return Character.class;
            }

            break;
        }

        case BYTE:
        {
            // Check if byte is in the set of possible classes to match.
            if (types.contains(byte.class))
            {
                return byte.class;
            }
            else if (types.contains(Byte.class))
            {
                return Byte.class;
            }

            break;
        }

        case SHORT:
        {
            // Check if short is in the set of possible classes to match.
            if (types.contains(short.class))
            {
                return short.class;
            }
            else if (types.contains(Short.class))
            {
                return Short.class;
            }

            break;
        }

        case INT:
        {
            // Check if int is in the set of possible classes to match.
            if (types.contains(int.class))
            {
                return int.class;
            }
            else if (types.contains(Integer.class))
            {
                return Integer.class;
            }

            break;
        }

        case LONG:
        {
            // Check if long is in the set of possible classes to match.
            if (types.contains(long.class))
            {
                return long.class;
            }
            else if (types.contains(Long.class))
            {
                return Long.class;
            }

            break;
        }

        case FLOAT:
        {
            // Check if float is in the set of possible classes to match.
            if (types.contains(float.class))
            {
                return float.class;
            }
            else if (types.contains(Float.class))
            {
                return Float.class;
            }

            break;
        }

        case DOUBLE:
        {
            // Check if double is in the set of possible classes to match.
            if (types.contains(double.class))
            {
                return double.class;
            }
            else if (types.contains(Double.class))
            {
                return Double.class;
            }

            break;
        }

        case STRING:
        {
            // Check if String is in the set of possible classes to match.
            if (types.contains(String.class))
            {
                return String.class;
            }

            break;
        }

        default:
        {
            throw new IllegalStateException("Unknown MultiTypeData type.");
        }
        }

        // Check if the multi type can be converted to a boolean and boolean is in the set of possible convertions.
        if (((d.typeFlags & BOOLEAN) != 0) && types.contains(boolean.class))
        {
            return boolean.class;
        }
        else if (((d.typeFlags & BOOLEAN) != 0) && types.contains(Boolean.class))
        {
            return Boolean.class;
        }

        // Check if the multi type can be converted to a byte and byte is in the set of possible convertions.
        else if (((d.typeFlags & BYTE) != 0) && types.contains(byte.class))
        {
            return byte.class;
        }
        else if (((d.typeFlags & BYTE) != 0) && types.contains(Byte.class))
        {
            return Byte.class;
        }

        // Check if the multi type can be converted to a char and char is in the set of possible convertions.
        else if (((d.typeFlags & CHAR) != 0) && types.contains(char.class))
        {
            return char.class;
        }
        else if (((d.typeFlags & CHAR) != 0) && types.contains(Character.class))
        {
            return Character.class;
        }

        // Check if the multi type can be converted to a short and short is in the set of possible convertions.
        else if (((d.typeFlags & SHORT) != 0) && types.contains(short.class))
        {
            return short.class;
        }
        else if (((d.typeFlags & SHORT) != 0) && types.contains(Short.class))
        {
            return Short.class;
        }

        // Check if the multi type can be converted to a int and int is in the set of possible convertions.
        else if (((d.typeFlags & INT) != 0) && types.contains(int.class))
        {
            return int.class;
        }
        else if (((d.typeFlags & INT) != 0) && types.contains(Integer.class))
        {
            return Integer.class;
        }

        // Check if the multi type can be converted to a long and long is in the set of possible convertions.
        else if (((d.typeFlags & LONG) != 0) && types.contains(long.class))
        {
            return long.class;
        }
        else if (((d.typeFlags & LONG) != 0) && types.contains(Long.class))
        {
            return Long.class;
        }

        // Check if the multi type can be converted to a float and float is in the set of possible convertions.
        else if (((d.typeFlags & FLOAT) != 0) && types.contains(float.class))
        {
            return float.class;
        }
        else if (((d.typeFlags & FLOAT) != 0) && types.contains(Float.class))
        {
            return Float.class;
        }

        // Check if the multi type can be converted to a double and double is in the set of possible convertions.
        else if (((d.typeFlags & DOUBLE) != 0) && types.contains(double.class))
        {
            return double.class;
        }
        else if (((d.typeFlags & DOUBLE) != 0) && types.contains(Double.class))
        {
            return Double.class;
        }

        // Check if the multi type can be converted to a String and String is in the set of possible convertions.
        else if (((d.typeFlags & STRING) != 0) && types.contains(String.class))
        {
            return String.class;
        }

        // No matching type convertion found so return null.
        else
        {
            return null;
        }
    }
For a set of types this method selects the best type to convert a given multi type data object into. This method
can be usefull when deciding which of several setter methods on a bean is the best one to convert the multi type
data obejct into before calling the beans setter method.

<p/>This method tries first to match the native type of the multi type data and then tries the other types in
this order: Object, boolean, char, byte, short, int, long, float, double, String. The Object type is only matched
if the multi type data object has a native Object type and the class of that object exactly matches one of the
possible classes to convert to.

<p/>If the set of classes to convert to contains a primitive class type, such as int.class, and this is matched
the primitive class will be returned, int.class in this case. If the set of classes to convert to contains a
wrapper class, such as Integer.class, and this is matched then this will be returned. The primitive classes are
always matched first so if both the primitive and wrapper versions are in the set to be matched then the
primitive version will be returned.

@param  d     The multi type data object to test for best convertion.
@param  types The possible set of classes to convert to.

@return The best matching class or null if none can be matched.