// we could magically make this work in many cases by doing
 // getAnyRef() (or getValue().unwrapped()), but anytime we
 // rely on that, we aren't doing the type conversions Config
 // usually does, and we will throw ClassCastException instead
 // of a nicer error message giving the name of the bad
 // setting. So, instead, we only support a limited number of
 // types plus you can always use Object, ConfigValue, Config,
 // ConfigObject, etc.  as an escape hatch.
 private static Object getValue(
     Class<?> beanClass,
     Type parameterType,
     Class<?> parameterClass,
     Config config,
     String configPropName) {
   if (parameterClass == Boolean.class || parameterClass == boolean.class) {
     return config.getBoolean(configPropName);
   } else if (parameterClass == Integer.class || parameterClass == int.class) {
     return config.getInt(configPropName);
   } else if (parameterClass == Double.class || parameterClass == double.class) {
     return config.getDouble(configPropName);
   } else if (parameterClass == Long.class || parameterClass == long.class) {
     return config.getLong(configPropName);
   } else if (parameterClass == String.class) {
     return config.getString(configPropName);
   } else if (parameterClass == Duration.class) {
     return config.getDuration(configPropName);
   } else if (parameterClass == ConfigMemorySize.class) {
     return config.getMemorySize(configPropName);
   } else if (parameterClass == Object.class) {
     return config.getAnyRef(configPropName);
   } else if (parameterClass == List.class) {
     return getListValue(beanClass, parameterType, parameterClass, config, configPropName);
   } else if (parameterClass == Map.class) {
     // we could do better here, but right now we don't.
     Type[] typeArgs = ((ParameterizedType) parameterType).getActualTypeArguments();
     if (typeArgs[0] != String.class || typeArgs[1] != Object.class) {
       throw new ConfigException.BadBean(
           "Bean property '"
               + configPropName
               + "' of class "
               + beanClass.getName()
               + " has unsupported Map<"
               + typeArgs[0]
               + ","
               + typeArgs[1]
               + ">, only Map<String,Object> is supported right now");
     }
     return config.getObject(configPropName).unwrapped();
   } else if (parameterClass == Config.class) {
     return config.getConfig(configPropName);
   } else if (parameterClass == ConfigObject.class) {
     return config.getObject(configPropName);
   } else if (parameterClass == ConfigValue.class) {
     return config.getValue(configPropName);
   } else if (parameterClass == ConfigList.class) {
     return config.getList(configPropName);
   } else if (hasAtLeastOneBeanProperty(parameterClass)) {
     return createInternal(config.getConfig(configPropName), parameterClass);
   } else {
     throw new ConfigException.BadBean(
         "Bean property "
             + configPropName
             + " of class "
             + beanClass.getName()
             + " has unsupported type "
             + parameterType);
   }
 }