/**
   * Create an internal native Task with the given native task (user)
   *
   * @param task the user native task that will be used to create the internal native task.
   * @return the created internal task.
   * @throws JobCreationException an exception if the factory cannot create the given task.
   */
  private static InternalTask createTask(Job userJob, NativeTask task) throws JobCreationException {
    if (((task.getCommandLine() == null) || (task.getCommandLine().length == 0))) {
      String msg = "The command line is null or empty and not generated !";
      logger.info(msg);
      throw new JobCreationException(msg);
    }

    try {
      String commandAndArguments = "\"" + Joiner.on("\" \"").join(task.getCommandLine()) + "\"";
      InternalTask scriptTask;
      if (isForkingTask()) {
        scriptTask =
            new InternalForkedScriptTask(
                new ScriptExecutableContainer(
                    new TaskScript(new SimpleScript(commandAndArguments, "native"))));
        configureRunAsMe(task);
      } else {
        scriptTask =
            new InternalScriptTask(
                new ScriptExecutableContainer(
                    new TaskScript(new SimpleScript(commandAndArguments, "native"))));
      }
      ForkEnvironment forkEnvironment = new ForkEnvironment();
      scriptTask.setForkEnvironment(forkEnvironment);
      // set task common properties
      setTaskCommonProperties(userJob, task, scriptTask);
      return scriptTask;

    } catch (Exception e) {
      throw new JobCreationException(e);
    }
  }
  /**
   * Create an internal java Task with the given java task (user)
   *
   * @param task the user java task that will be used to create the internal java task.
   * @return the created internal task.
   * @throws JobCreationException an exception if the factory cannot create the given task.
   */
  @SuppressWarnings("unchecked")
  private static InternalTask createTask(Job userJob, JavaTask task) throws JobCreationException {
    InternalTask javaTask;

    if (task.getExecutableClassName() != null) {
      HashMap<String, byte[]> args = task.getSerializedArguments();

      try {
        if (isForkingTask()) {
          javaTask =
              new InternalForkedScriptTask(
                  new ScriptExecutableContainer(
                      new TaskScript(
                          new SimpleScript(
                              task.getExecutableClassName(),
                              JavaClassScriptEngineFactory.JAVA_CLASS_SCRIPT_ENGINE_NAME,
                              new Serializable[] {args}))));
          javaTask.setForkEnvironment(task.getForkEnvironment());
          configureRunAsMe(task);
        } else {
          javaTask =
              new InternalScriptTask(
                  new ScriptExecutableContainer(
                      new TaskScript(
                          new SimpleScript(
                              task.getExecutableClassName(),
                              JavaClassScriptEngineFactory.JAVA_CLASS_SCRIPT_ENGINE_NAME,
                              new Serializable[] {args}))));
        }
      } catch (InvalidScriptException e) {
        throw new JobCreationException(e);
      }
    } else {
      String msg =
          "You must specify your own executable task class to be launched (in every task)!";
      logger.info(msg);
      throw new JobCreationException(msg);
    }

    // set task common properties
    try {
      setTaskCommonProperties(userJob, task, javaTask);
    } catch (Exception e) {
      throw new JobCreationException(e);
    }
    return javaTask;
  }
  InternalTask toInternalTask(InternalJob internalJob) throws InvalidScriptException {
    TaskId taskId = createTaskId(internalJob);

    InternalTask internalTask;

    if (taskType.equals(SCRIPT_TASK)) {
      internalTask = new InternalScriptTask();
    } else if (taskType.equals(FORKED_SCRIPT_TASK)) {
      internalTask = new InternalForkedScriptTask();
    } else {
      throw new IllegalStateException("Unexpected stored task type: " + taskType);
    }

    internalTask.setId(taskId);
    internalTask.setDescription(getDescription());
    internalTask.setStatus(getTaskStatus());
    internalTask.setJobInfo(internalJob.getJobInfo());
    internalTask.setName(getTaskName());
    internalTask.setExecutionDuration(getExecutionDuration());
    internalTask.setFinishedTime(getFinishedTime());
    internalTask.setStartTime(getStartTime());
    internalTask.setExecutionHostName(getExecutionHostName());
    internalTask.setCancelJobOnError(isCancelJobOnError());
    internalTask.setPreciousLogs(isPreciousLogs());
    internalTask.setPreciousResult(isPreciousResult());
    internalTask.setRunAsMe(isRunAsMe());
    internalTask.setWallTime(getWallTime());
    internalTask.setMaxNumberOfExecution(getMaxNumberOfExecution());
    internalTask.setRestartTaskOnError(getRestartMode());
    internalTask.setFlowBlock(getFlowBlock());
    internalTask.setIterationIndex(getIteration());
    internalTask.setReplicationIndex(getReplication());
    internalTask.setMatchingBlock(getMatchingBlock());

    ForkEnvironment forkEnv = new ForkEnvironment();
    forkEnv.setJavaHome(javaHome);

    List<String> additionalClasspath = getAdditionalClasspath();
    if (additionalClasspath != null) {
      for (String classpath : additionalClasspath) {
        forkEnv.addAdditionalClasspath(classpath);
      }
    }

    List<String> jvmArguments = getJvmArguments();
    if (jvmArguments != null) {
      for (String jvmArg : jvmArguments) {
        forkEnv.addJVMArgument(jvmArg);
      }
    }

    List<EnvironmentModifierData> envModifiers = getEnvModifiers();

    if (envModifiers != null) {
      for (EnvironmentModifierData envModifier : envModifiers) {
        forkEnv.addSystemEnvironmentVariable(envModifier.getName(), envModifier.getValue());
      }
    }

    if (envScript != null) {
      forkEnv.setEnvScript(envScript.createSimpleScript());
    }

    internalTask.setForkEnvironment(forkEnv);

    return internalTask;
  }