class TypeProducerFactory {

    public TypeProducer createTypeProducer(Class<?> aClass, Type genericType) {
        if (aClass == List.class || aClass == Set.class || aClass == SortedSet.class) {
            Class<?> actualTypeArgument = null;
            if (genericType != null) {
                actualTypeArgument = getActualTypeArgument(genericType);
            }
            Method methodValueOf;
            Constructor<?> constructor;

            if (actualTypeArgument == String.class || actualTypeArgument == null) {
                return new CollectionStringProducer(aClass);
            } else if ((methodValueOf = getStringValueOfMethod(actualTypeArgument)) != null) {
                return new CollectionStringValueOfProducer(aClass, methodValueOf);
            } else if ((constructor = getStringConstructor(actualTypeArgument)) != null) {
                return new CollectionStringConstructorProducer(aClass, constructor);
            }
        } else {
            Method methodValueOf;
            Constructor<?> constructor;

            if (aClass.isPrimitive()) {
                return new PrimitiveTypeProducer(aClass);
            } else if (aClass == String.class) {
                return new StringProducer();
            } else if ((methodValueOf = getStringValueOfMethod(aClass)) != null) {
                return new StringValueOfProducer(methodValueOf);
            } else if ((constructor = getStringConstructor(aClass)) != null) {
                return new StringConstructorProducer(constructor);
            }
        }

        throw new IllegalArgumentException(String.format("Unsupported type %s", aClass));
    }

}