public static void addTask(JobPlan object, ObjectBroker Objbroker) throws IOException {
   List<SearchResultItem> items =
       Objbroker.searches.searchExecutableObjects(ProcessSpecificCLI.U_ADDTASK);
   if (items.isEmpty()) {
     System.out.println(" %% No Task Found Matching Pattern: " + ProcessSpecificCLI.U_ADDTASK);
   } else {
     for (int g = 0; g < items.size(); g++) {
       JobPlanTask jptask = Objbroker.jobPlans.getTaskFromName(items.get(g).getName());
       jptask.setX(g + 1);
       jptask.setY(2);
       System.out.println(
           "\t ++ UPDATE: Add Task to JobPlan: [ "
               + jptask.getTaskName()
               + " | "
               + jptask.getType()
               + " | {"
               + jptask.getX()
               + ","
               + jptask.getY()
               + "} ]");
       object.addTask(jptask);
       object.format();
     }
   }
 }
  public static ArrayList<JobPlanTask> GetMatchingTaskList(JobPlan object, ObjectBroker Objbroker) {
    // contains the list of tasks to modify in currently processing workflow
    ArrayList<JobPlanTask> selectedTasks = new ArrayList<JobPlanTask>();
    String TaskNameFilter = ProcessSpecificCLI.F_TASKNAME;
    String TaskNumberFilter = ProcessSpecificCLI.F_TASKNUMBER;

    if (ProcessSpecificCLI.F_TASKNAME == null || ProcessSpecificCLI.F_TASKNAME.equals("")) {
      TaskNameFilter = ".*";
    }
    if (ProcessSpecificCLI.F_TASKNUMBER == null || ProcessSpecificCLI.F_TASKNUMBER.equals("")) {
      TaskNumberFilter = ".*";
    }

    Iterator<JobPlanTask> iter = object.taskIterator();
    while (iter.hasNext()) {
      JobPlanTask jpt = iter.next();
      if (jpt.getTaskName().matches(TaskNameFilter)) {
        if (Integer.toString(jpt.getLnr()).matches(TaskNumberFilter)) {
          selectedTasks.add(jpt);
        }
      }
    }
    return selectedTasks;
  }
 public static void delTaskDepLatest(JobPlan object, ObjectBroker Objbroker) {
   ArrayList<JobPlanTask> selectedTasks = GetMatchingTaskList(object, Objbroker);
   for (int i = 0; i < selectedTasks.size(); i++) {
     JobPlanTask jptask = selectedTasks.get(i);
     jptask.dependencies().setAtTheLatest(false);
     System.out.println(
         "\t ++ UPDATE: Remove Latest Option on Task Dependency: [ {"
             + jptask.getTaskName()
             + "("
             + jptask.getLnr()
             + ") | "
             + jptask.getType()
             + " | {"
             + jptask.getX()
             + ","
             + jptask.getY()
             + "} ]");
   }
 }
  public static void addTaskAtPosition(JobPlan object, ObjectBroker Objbroker) throws IOException {

    String[] RawVals = ProcessSpecificCLI.U_ADDTASKATPOSITION.split(","); // splits ["TASK","1","2"]
    String TaskName = RawVals[0].replace("[", "");
    String PosX = RawVals[1];
    int iPosX = Integer.parseInt(PosX);
    String PosY = RawVals[2].replace("]", "");
    int iPosY = Integer.parseInt(PosY);
    System.out.println(" ++ Adding Task: " + TaskName + " at: [" + iPosX + "," + iPosY + "]");
    JobPlanTask jptask = Objbroker.jobPlans.getTaskFromName(TaskName);
    jptask.setX(iPosX);
    jptask.setY(iPosY);
    System.out.println(
        "\t ++ UPDATE: Add Task to JobPlan: [ "
            + jptask.getTaskName()
            + " | "
            + jptask.getType()
            + " | {"
            + jptask.getX()
            + ","
            + jptask.getY()
            + "} ]");
    object.addTask(jptask);
  }
  public static void removeTask(WorkflowLoop object, ObjectBroker Objbroker) {
    Iterator<JobPlanTask> TaskIt = object.iterator();
    ArrayList<JobPlanTask> TasksToRemove = new ArrayList<JobPlanTask>();

    while (TaskIt.hasNext()) {
      JobPlanTask task = TaskIt.next();
      try {
        if (task.getTaskName().matches(ProcessSpecificCLI.U_REMTASK)) {
          System.out.println(
              "\t ++ UPDATE: Remove Task from JobPlan: [ "
                  + task.getTaskName()
                  + " | "
                  + task.getType()
                  + " | {"
                  + task.getX()
                  + ","
                  + task.getY()
                  + "} ]");
          TasksToRemove.add(task);
          // object.removeTask(task);
        }
      } catch (PatternSyntaxException e) {
        System.out.println(
            " -- Internal Error. The Regular Expression Used for one of the Filters is invalid - See Error Below: "
                + e.getDescription());
        System.out.println("\t\t" + e.toString());
        System.out.println(
            " %% HINT: '*' and '+' are NOT valid Regular Expressions on their own. '*' marks '0 or more' and '+' marks '1 or more', but you need to specify a preceeding character or string");
        System.out.println(
            " %% HINT: Ex: invalid expressions: '*ABC*', '*.123', '+DEF'. Valid expressions: '.*ABC.*', '.*.123', '.+DEF' ");

        System.exit(999);
      }
    }
    // seems like the for loop below could have been included in the while loop above? it cant
    // because it creates a problem of concurrence of requests (due to the fact that the removeTask
    // method uses also an iterator!!)
    for (int j = 0; j < TasksToRemove.size(); j++) {
      object.removeTask(TasksToRemove.get(j));
    }
  }
  public static void CopyTaskPreConditions(WorkflowIF object, ObjectBroker Objbroker)
      throws IOException {
    // contains the list of tasks to modify in currently processing workflow
    ArrayList<JobPlanTask> selectedTasks = new ArrayList<JobPlanTask>();
    String TaskFilter = ProcessSpecificCLI.L_F_TASKNAME;
    if (ProcessSpecificCLI.F_TASKNAME.equals("")) {
      TaskFilter = ".*";
    }
    Iterator<JobPlanTask> FalseIter = object.falseTasksIterator();
    while (FalseIter.hasNext()) {
      JobPlanTask jpt = FalseIter.next();
      if (jpt.getTaskName().matches(TaskFilter)) {
        selectedTasks.add(jpt);
      }
    }
    Iterator<JobPlanTask> TrueIter = object.falseTasksIterator();
    while (TrueIter.hasNext()) {
      JobPlanTask jpt = TrueIter.next();
      if (jpt.getTaskName().matches(TaskFilter)) {
        selectedTasks.add(jpt);
      }
    }
    // at this point, we know which tasks to update in the current workflow..
    String[] Patterns =
        consistencyUtils.getUpdatePattern(ProcessSpecificCLI.U_COPY_TASK_PRECONDITIONS);
    String JobNameToCopy = Patterns[0];
    String WorkflowNameToCopy = Patterns[1];
    // MISSING: check for the existence of both ... eventually ?

    // getting the actual task to copy from.
    UC4Object wrkObj = Objbroker.common.openObject(WorkflowNameToCopy, true);
    boolean WorkflowAndTaskOriginFound = true;
    if (wrkObj == null) {
      System.out.println(
          "\t -- Error. Workflow used as origin could not be found: " + WorkflowNameToCopy);
      WorkflowAndTaskOriginFound = false; // Workflow doesnt exist
    }

    if (WorkflowAndTaskOriginFound) {
      JobPlan OriJPlan = Objbroker.jobPlans.getJobPlanFromObject(wrkObj);
      JobPlanTask jptOrigin = Objbroker.jobPlans.getTaskFromNameAndJobPlan(OriJPlan, JobNameToCopy);
      if (jptOrigin == null) {
        System.out.println(
            "\t -- Error. Workflow used as origin was found, but a corrsponding task for the following object cound not be found: "
                + JobNameToCopy);
        WorkflowAndTaskOriginFound = false; // task doesnt exist
      }
      if (WorkflowAndTaskOriginFound) {
        // getting all preconditions in an array
        ArrayList<ConditionOrAction> AllActionsToCopy = new ArrayList<ConditionOrAction>();
        Iterator<ConditionOrAction> AllActionsIter = jptOrigin.preConditions().iterator();
        while (AllActionsIter.hasNext()) {
          ConditionOrAction CoA = AllActionsIter.next();
          AllActionsToCopy.add(CoA);
        }

        // Now, for each selected Tasks we copy over all preconditions
        for (int y = 0; y < selectedTasks.size(); y++) {
          System.out.println(
              "\t ++ UPDATE: Task Marked for PreCondition Copy - [Task Destination] <= [Task Source]: "
                  + "[ "
                  + selectedTasks.get(y).getTaskName()
                  + ":"
                  + object.getName()
                  + " ] <= [ "
                  + JobNameToCopy
                  + ":"
                  + WorkflowNameToCopy
                  + " ]");
          selectedTasks.get(y).preConditions().clear();
          for (int t = 0; t < AllActionsToCopy.size(); t++) {
            selectedTasks.get(y).preConditions().add(AllActionsToCopy.get(t));
          }
        }
      }
    }
  }
  public static void replaceTask(JobPlan object, ObjectBroker Objbroker) throws IOException {
    String[] Patterns = consistencyUtils.getUpdatePattern(ProcessSpecificCLI.U_REPTASK);
    String OldValue = Patterns[0];
    String NewValue = Patterns[1];

    Iterator<JobPlanTask> TaskIt = object.taskIterator();
    while (TaskIt.hasNext()) {
      JobPlanTask oriTask = TaskIt.next();
      if (oriTask.getTaskName().contains(OldValue)) {

        String NewTaskName = oriTask.getTaskName().replace(OldValue, NewValue);
        // make sure its a valid object?

        boolean NewTaskexists = true;
        List<SearchResultItem> items = Objbroker.searches.searchObject(NewTaskName);
        if (items.isEmpty()) {
          System.out.println(
              " -- Error: Trying to replace with non-existant task: "
                  + NewTaskName
                  + " (Hint: Pattern for replacement may be incorrect?)");
          NewTaskexists = false;
        }
        if (NewTaskexists) {
          JobPlanTask jptask = Objbroker.jobPlans.getTaskFromName(NewTaskName);
          // [ Origin Task Type | Origin Task Name | Origin Task position ] => [ New Task Type | New
          // Task Name | New Task position ]
          System.out.println(
              "\t ++ UPDATE: Replace Task from JobPlan : "
                  + " [ "
                  + oriTask.getType()
                  + " | "
                  + oriTask.getTaskName()
                  + " | {"
                  + oriTask.getX()
                  + ","
                  + oriTask.getY()
                  + "} ] => "
                  + " [ "
                  + jptask.getType()
                  + " | "
                  + jptask.getTaskName()
                  + " | {"
                  + oriTask.getX()
                  + ","
                  + oriTask.getY()
                  + "} ]");
          object.replaceTask(oriTask, jptask);
        }
      }
    }
  }
  public static void addDependency(JobPlan object, ObjectBroker Objbroker) throws IOException {

    // format can be ["TASKNAME","PREDECESSORNAME","STATUS"] or:
    // ["TASKNAME(4)","PREDECESSORNAME","STATUS"] or: ["TASKNAME","PREDECESSORNAME(5)","STATUS"]
    // => the task number isnt mandatory but is useful when the same job exists as several tasks
    // within one same WF

    // Getting the task Name and Task Number (if passed)
    String[] RawVals = ProcessSpecificCLI.U_ADDDEPENDENCY.split(",");
    String TaskName = RawVals[0].replace("[", "");
    String SanitizedTaskName = "";
    int TaskNameNumber = -1;
    String SanitizedPredecessorTaskName = "";
    int PredecessorTaskNameNumber = -1;
    if (TaskName.contains("(") && TaskName.contains(")")) {
      SanitizedTaskName = TaskName.split("\\(")[0];
      TaskNameNumber = Integer.parseInt(TaskName.split("\\(")[1].replace(")", ""));
    } else {
      SanitizedTaskName = TaskName;
    }

    // Getting the Predecessor task Name and Task Number (if passed)
    String TaskPredecessor = RawVals[1];
    String TaskStatus = RawVals[2].replace("]", "");

    if (TaskPredecessor.contains("(") && TaskPredecessor.contains(")")) {
      SanitizedPredecessorTaskName = TaskPredecessor.split("\\(")[0];
      PredecessorTaskNameNumber =
          Integer.parseInt(TaskPredecessor.split("\\(")[1].replace(")", ""));
    } else {
      SanitizedPredecessorTaskName = TaskPredecessor;
    }

    // Getting the task state.. no control here :(
    TaskState tState = new TaskState(TaskStatus);

    // handling the case where the Task Name is END (end of WF)
    ArrayList<JobPlanTask> TaskList = new ArrayList<JobPlanTask>();
    if (SanitizedTaskName.equalsIgnoreCase("END")) {
      TaskList.add(object.getEndTask());
    } else {
      TaskList = Objbroker.jobPlans.getTasksFromNameAndJobPlan(object, SanitizedTaskName);
    }

    // handling the case where the Predecessor Task Name is START (start of WF)
    ArrayList<JobPlanTask> PredecessorTaskList = new ArrayList<JobPlanTask>();
    if (SanitizedPredecessorTaskName.equalsIgnoreCase("START")) {
      PredecessorTaskList.add(object.getStartTask());
    } else {
      PredecessorTaskList =
          Objbroker.jobPlans.getTasksFromNameAndJobPlan(object, SanitizedPredecessorTaskName);
    }

    // For each task found
    for (int h = 0; h < TaskList.size(); h++) {
      JobPlanTask jptask = TaskList.get(h);
      // for each predecessor found
      for (int k = 0; k < PredecessorTaskList.size(); k++) {
        JobPlanTask jppredecessortask = PredecessorTaskList.get(k);
        // only create a dependency if: eithere there is no task number specified or.. if they
        // match.
        if ((TaskNameNumber == -1 || jptask.getLnr() == TaskNameNumber)
            && (PredecessorTaskNameNumber == -1
                || jppredecessortask.getLnr() == PredecessorTaskNameNumber)) {
          System.out.println(
              "\t ++ UPDATE: Adding Dependency to: "
                  + jptask.getTaskName()
                  + "("
                  + jptask.getLnr()
                  + ")"
                  + " on: "
                  + jppredecessortask.getTaskName()
                  + "("
                  + jppredecessortask.getLnr()
                  + ")"
                  + " in Status: "
                  + tState
                  + "");
          jptask.dependencies().addDependency(jppredecessortask, tState);
        }
      }
    }
  }