private <S> S convertValueTo(final Object value, final FluentClass<S> klassToCreate) {
        try
        {
            final List<FluentMethod> valueOfMethods =
                    klassToCreate.methods(hasName("valueOf").and(hasArguments(value.getClass())).and(
                            hasType(klass)));

            if (!valueOfMethods.isEmpty()) {
                return (S) valueOfMethods.get(0).call(value).value();
            }

            final List<FluentConstructor<S>> singleArgumentConstructors =
                    klassToCreate.constructors(hasArguments(value.getClass()));

            if (!singleArgumentConstructors.isEmpty()) {
                return singleArgumentConstructors.get(0).call(value).value();
            }

            final List<FluentConstructor<S>> typeTokenConstructors =
                    klassToCreate.constructors(hasArguments(value.getClass(), Type.class));

            if (!typeTokenConstructors.isEmpty()) {
                return typeTokenConstructors.get(0).call(value, klassToCreate.type()).value();
            }

            if (klassToCreate.classUnderReflection().equals(Character.class) && value.getClass().equals(String.class)) {
                // special case for characters from string
                final String stringValue = (String) value;
                if (stringValue.length() == 1) {
                    return (S) Character.valueOf(stringValue.charAt(0));
                }
                else
                {
                    validationErrorBuilder.invalidValueForType(
                            specification,
                            String.format("value is not a character (%s)", value));
                    return null;
                }
            }
        } catch (final InvocationTargetRuntimeException e) {
            final Throwable cause = e.getExceptionThrownByInvocationTarget();
            if (cause instanceof NumberFormatException)
            {
                validationErrorBuilder.invalidValueForType(
                        specification,
                        unsupportedNumberFormatMessage((NumberFormatException) cause));
            }
            else
            {
                validationErrorBuilder.invalidValueForType(specification, cause.getMessage());
            }
            return null;
        } catch (final ReflectionRuntimeException e)
        {
            validationErrorBuilder.unableToConstructType(specification, e.getMessage());
            return null;
        }

        throw new ClassCastException(String.format("cannot convert %s to %s", value.getClass(), klass));
    }