/**
  * A helper method that returns the parsed default value of a given NamedParameter.
  *
  * @return null or an empty set if there is no default value, the default value (or set of values)
  *     otherwise.
  * @throws ClassHierarchyException if a default value was specified, but could not be parsed, or
  *     if a set of values were specified for a non-set parameter.
  */
 @SuppressWarnings("unchecked")
 @Override
 public <T> T parseDefaultValue(final NamedParameterNode<T> name) {
   final String[] vals = name.getDefaultInstanceAsStrings();
   final T[] ret = (T[]) new Object[vals.length];
   for (int i = 0; i < vals.length; i++) {
     final String val = vals[i];
     try {
       ret[i] = parse(name, val);
     } catch (final ParseException e) {
       throw new ClassHierarchyException("Could not parse default value", e);
     }
   }
   if (name.isSet()) {
     return (T) new HashSet<T>(Arrays.asList(ret));
   } else if (name.isList()) {
     return (T) new ArrayList<T>(Arrays.asList(ret));
   } else {
     if (ret.length == 0) {
       return null;
     } else if (ret.length == 1) {
       return ret[0];
     } else {
       throw new IllegalStateException(
           "Multiple defaults for non-set named parameter! " + name.getFullName());
     }
   }
 }
 public ClassHierarchyImpl(
     final URL[] jars, final Class<? extends ExternalConstructor<?>>[] parameterParsers) {
   this.namespace = JavaNodeFactory.createRootPackageNode();
   this.jars = new ArrayList<>(Arrays.asList(jars));
   this.loader = new URLClassLoader(jars, this.getClass().getClassLoader());
   for (final Class<? extends ExternalConstructor<?>> p : parameterParsers) {
     try {
       parameterParser.addParser(p);
     } catch (final BindException e) {
       throw new IllegalArgumentException("Could not register parameter parsers", e);
     }
   }
 }