/**
   * Execute a collection of ScriptModules identified by moduleId.
   *
   * @param moduleIds moduleIds for modules to execute
   * @param executable execution logic to be performed for each module.
   * @param moduleLoader loader which manages the modules.
   * @return list of the outputs from the executable.
   */
  public List<V> executeModules(
      List<String> moduleIds,
      ScriptModuleExecutable<V> executable,
      ScriptModuleLoader moduleLoader) {
    Objects.requireNonNull(moduleIds, "moduleIds");
    Objects.requireNonNull(executable, "executable");
    Objects.requireNonNull(moduleLoader, "moduleLoader");

    List<ScriptModule> modules = new ArrayList<ScriptModule>(moduleIds.size());
    for (String moduleId : moduleIds) {
      ScriptModule module = moduleLoader.getScriptModule(ModuleId.create(moduleId));
      if (module != null) {
        modules.add(module);
      }
    }
    return executeModules(modules, executable);
  }