/**
   * Loads profile and create a new {@link ExecutionTask}.
   *
   * @param profile target profile
   * @param script target script
   * @param batchArguments current batch arguments
   * @param yaessArguments current controll arguments
   * @return the created task
   * @throws InterruptedException if interrupted while configuring services
   * @throws IOException if failed to configure services
   * @throws IllegalArgumentException if some parameters were {@code null}
   * @since 0.2.6
   */
  public static ExecutionTask load(
      YaessProfile profile,
      Properties script,
      Map<String, String> batchArguments,
      Map<String, String> yaessArguments)
      throws InterruptedException, IOException {
    if (profile == null) {
      throw new IllegalArgumentException("profile must not be null"); // $NON-NLS-1$
    }
    if (script == null) {
      throw new IllegalArgumentException("script must not be null"); // $NON-NLS-1$
    }
    if (batchArguments == null) {
      throw new IllegalArgumentException("batchArguments must not be null"); // $NON-NLS-1$
    }
    if (yaessArguments == null) {
      throw new IllegalArgumentException("yaessArguments must not be null"); // $NON-NLS-1$
    }
    LOG.debug("Loading execution monitor feature");
    ExecutionMonitorProvider monitors = profile.getMonitors().newInstance();

    LOG.debug("Loading execution lock feature");
    ExecutionLockProvider locks = profile.getLocks().newInstance();

    LOG.debug("Loading job scheduling feature");
    JobScheduler scheduler = profile.getScheduler().newInstance();

    LOG.debug("Loading hadoop execution feature");
    HadoopScriptHandler hadoopHandler = profile.getHadoopHandler().newInstance();

    LOG.debug("Loading command execution features");
    Map<String, CommandScriptHandler> commandHandlers = new HashMap<String, CommandScriptHandler>();
    for (Map.Entry<String, ServiceProfile<CommandScriptHandler>> entry :
        profile.getCommandHandlers().entrySet()) {
      commandHandlers.put(entry.getKey(), entry.getValue().newInstance());
    }

    LOG.debug("Extracting batch script");
    BatchScript batch = BatchScript.load(script);

    ExecutionTask result =
        new ExecutionTask(
            monitors, locks, scheduler, hadoopHandler, commandHandlers, batch, batchArguments);

    LOG.debug("Applying definitions");
    Map<String, String> copyDefinitions = new TreeMap<String, String>(yaessArguments);
    consumeRuntimeContext(result, copyDefinitions, batch);
    consumeSkipFlows(result, copyDefinitions, batch);
    consumeSerializeFlows(result, copyDefinitions, batch);
    checkRest(copyDefinitions);

    return result;
  }