private Class<?> getType(ClassLoader loader, InjectionTarget target) {
    try {
      final Class<?> clazz = loader.loadClass(target.getInjectionTargetClass());

      try {
        final Field field = clazz.getDeclaredField(target.getInjectionTargetName());
        return field.getType();
      } catch (NoSuchFieldException e) {
      }

      // TODO Technically we should match by case
      final String bestName = "set" + StringUtils.capitalize(target.getInjectionTargetName());
      final String name = "set" + target.getInjectionTargetName().toLowerCase();
      Class<?> found = null;
      for (Method method : clazz.getDeclaredMethods()) {
        if (method.getParameterTypes().length == 1) {
          if (method.getName().equals(bestName)) {
            return method.getParameterTypes()[0];
          } else if (method.getName().toLowerCase().equals(name)) {
            found = method.getParameterTypes()[0];
          }
        }
      }

      if (found != null) {
        return found;
      }

    } catch (Throwable e) {
    }

    return Object.class;
  }
  private void fillInMissingType(ClassLoader loader, EnvEntry entry) {
    if (entry.getType() != null) return;

    // If it has the lookup supplied we don't care if there is no type
    if (entry.getLookupName() != null) return;

    // We can't imply type without at least one injection point
    if (entry.getInjectionTarget().size() == 0) return;

    final Set<Class> types = new HashSet<Class>();

    for (InjectionTarget target : entry.getInjectionTarget()) {
      if (target.getInjectionTargetClass() == null) continue;
      if (target.getInjectionTargetName() == null) continue;

      types.add(getType(loader, target));
    }

    normalize(types);

    final Class<?> type = (types.size() == 1) ? types.iterator().next() : String.class;

    entry.setType(type.getName());
  }