class ScenarioBeanUtil {

    public static Object convertValue(String className, Object cleanValue, ClassLoader classLoader) {
        // "null" string is converted to null
        cleanValue = "null".equals(cleanValue) ? null : cleanValue;

        if (!isPrimitive(className) && cleanValue == null) {
            return null;
        }

        Class<?> clazz = loadClass(className, classLoader);

        // if it is not a String, it has to be an instance of the desired type
        if (!(cleanValue instanceof String)) {
            if (clazz.isInstance(cleanValue)) {
                return cleanValue;
            }
            throw new IllegalArgumentException(new StringBuilder().append("Object ").append(cleanValue)
                                                       .append(" is not a String or an instance of ").append(className).toString());
        }

        String value = (String) cleanValue;

        try {
            if (clazz.isAssignableFrom(String.class)) {
                return value;
            } else if (clazz.isAssignableFrom(Boolean.class) || clazz.isAssignableFrom(boolean.class)) {
                return parseBoolean(value);
            } else if (clazz.isAssignableFrom(Integer.class) || clazz.isAssignableFrom(int.class)) {
                return Integer.parseInt(cleanStringForNumberParsing(value));
            } else if (clazz.isAssignableFrom(Long.class) || clazz.isAssignableFrom(long.class)) {
                return Long.parseLong(cleanStringForNumberParsing(value));
            } else if (clazz.isAssignableFrom(Double.class) || clazz.isAssignableFrom(double.class)) {
                return Double.parseDouble(cleanStringForNumberParsing(value));
            } else if (clazz.isAssignableFrom(Float.class) || clazz.isAssignableFrom(float.class)) {
                return Float.parseFloat(cleanStringForNumberParsing(value));
            } else if (clazz.isAssignableFrom(Character.class) || clazz.isAssignableFrom(char.class)) {
                return parseChar(value);
            } else if (clazz.isAssignableFrom(Byte.class) || clazz.isAssignableFrom(byte.class)) {
                return Byte.parseByte(value);
            } else if (clazz.isAssignableFrom(Short.class) || clazz.isAssignableFrom(short.class)) {
                return Short.parseShort(cleanStringForNumberParsing(value));
            } else if (clazz.isAssignableFrom(LocalDate.class)) {
                return LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            } else if (Enum.class.isAssignableFrom(clazz)) {
                return Enum.valueOf(((Class<? extends Enum>) clazz), value);
            }
        } catch (RuntimeException e) {
            throw new IllegalArgumentException(new StringBuilder().append("Impossible to parse '")
                                                       .append(value).append("' as ").append(className).append(" [")
                                                       .append(e.getMessage()).append("]").toString());
        }

        throw new IllegalArgumentException(new StringBuilder().append("Class ").append(className)
                                                   .append(" is not natively supported. Please use an MVEL expression" +
                                                                   " to use it.").toString());
    }

    private  ScenarioBeanUtil();

}