/**
   * Finds a class by class name using the auto-import information provided.
   *
   * @param className is the class name to find
   * @return class
   * @throws ClassNotFoundException if the class cannot be loaded
   */
  protected Class resolveClassInternal(String className) throws ClassNotFoundException {
    // Attempt to retrieve the class with the name as-is
    try {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      return Class.forName(className, true, cl);
    } catch (ClassNotFoundException e) {
      if (log.isDebugEnabled()) {
        log.debug("Class not found for resolving from name as-is '" + className + "'");
      }
    }

    // Try all the imports
    for (String importName : imports) {
      boolean isClassName = isClassName(importName);

      // Import is a class name
      if (isClassName) {
        if (importName.endsWith(className)) {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          return Class.forName(importName, true, cl);
        }
      } else {
        // Import is a package name
        String prefixedClassName = getPackageName(importName) + '.' + className;
        try {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          return Class.forName(prefixedClassName, true, cl);
        } catch (ClassNotFoundException e) {
          if (log.isDebugEnabled()) {
            log.debug("Class not found for resolving from name '" + prefixedClassName + "'");
          }
        }
      }
    }

    // try to resolve from method references
    for (String name : methodInvocationRef.keySet()) {
      if (JavaClassHelper.isSimpleNameFullyQualfied(className, name)) {
        try {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          return Class.forName(name, true, cl);
        } catch (ClassNotFoundException e1) {
          if (log.isDebugEnabled()) {
            log.debug("Class not found for resolving from method invocation ref:" + name);
          }
        }
      }
    }

    // No import worked, the class isn't resolved
    throw new ClassNotFoundException("Unknown class " + className);
  }
  public Pair<Class, String> resolveSingleRow(String name)
      throws EngineImportException, EngineImportUndefinedException {
    Pair<String, String> pair = singleRowFunctions.get(name);
    if (pair == null) {
      pair = singleRowFunctions.get(name.toLowerCase());
    }
    if (pair == null) {
      throw new EngineImportUndefinedException("A function named '" + name + "' is not defined");
    }

    Class clazz;
    try {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      clazz = Class.forName(pair.getFirst(), true, cl);
    } catch (ClassNotFoundException ex) {
      throw new EngineImportException(
          "Could not load single-row function class by name '" + pair.getFirst() + "'", ex);
    }
    return new Pair<Class, String>(clazz, pair.getSecond());
  }
  public AggregationSupport resolveAggregation(String name)
      throws EngineImportException, EngineImportUndefinedException {
    String className = aggregationFunctions.get(name);
    if (className == null) {
      className = aggregationFunctions.get(name.toLowerCase());
    }
    if (className == null) {
      throw new EngineImportUndefinedException("A function named '" + name + "' is not defined");
    }

    Class clazz;
    try {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      clazz = Class.forName(className, true, cl);
    } catch (ClassNotFoundException ex) {
      throw new EngineImportException(
          "Could not load aggregation class by name '" + className + "'", ex);
    }

    Object object;
    try {
      object = clazz.newInstance();
    } catch (InstantiationException e) {
      throw new EngineImportException(
          "Error instantiating aggregation class by name '" + className + "'", e);
    } catch (IllegalAccessException e) {
      throw new EngineImportException(
          "Illegal access instatiating aggregation function class by name '" + className + "'", e);
    }

    if (!(object instanceof AggregationSupport)) {
      throw new EngineImportException(
          "Aggregation class by name '" + className + "' does not subclass AggregationSupport");
    }
    return (AggregationSupport) object;
  }