private HNSubSet getTasksWithEmptyOutputPlaces(int task) {

    HNSubSet tasksEmptyOutPlaces;
    HNSubSet inputTasks;

    int inputTask;
    HNSet outputSubsets;

    inputTasks = hNet.getAllElementsInputSet(task);

    tasksEmptyOutPlaces = new HNSubSet();

    for (int iInputTasks = 0; iInputTasks < inputTasks.size(); iInputTasks++) {
      inputTask = inputTasks.get(iInputTasks);
      outputSubsets = auxMapping.getRelatedSubsets(task, inputTask);
      if (outputSubsets != null) {
        if (!allSubsetsAreMarked(inputTask, outputSubsets)) {
          tasksEmptyOutPlaces.add(inputTask);
        }
      } else {
        tasksEmptyOutPlaces.add(inputTask);
      }
    }

    return tasksEmptyOutPlaces;
  }
  private HNSubSet getAllOutputElementsOfDuplicates(HNSubSet duplicates) {
    // Returns the union set of the output tasks of the tasks in
    // "duplicates".
    // The returned union set has already the codes mapped to the ATEs in
    // the log!
    HNSubSet union = new HNSubSet();
    HNSubSet allElements;

    for (int i = 0; i < duplicates.size(); i++) {
      allElements = hNet.getAllElementsOutputSet(duplicates.get(i));
      for (int j = 0; j < allElements.size(); j++) {
        union.add(hNet.getDuplicatesMapping()[allElements.get(j)]);
      }
    }

    return union;
  }
  /** Returns the current enabled elements at the current marking. */
  public HNSubSet getCurrentEnabledElements() {

    int element = -1;
    HNSubSet disabledElements = null;

    disabledElements = new HNSubSet();
    for (int iPossiblyEnabledElements = 0;
        iPossiblyEnabledElements < possiblyEnabledElements.size();
        iPossiblyEnabledElements++) {
      element = possiblyEnabledElements.get(iPossiblyEnabledElements);
      if (!isEnabled(element)) {
        disabledElements.add(element);
      }
    }

    possiblyEnabledElements.removeAll(disabledElements);

    return possiblyEnabledElements;
  }
  /** Sets the marking to the initial marking. */
  public void reset() {

    Iterator outElements = null;
    HNSubSet outSubset = null;

    numberTokens = 1; // in the source place
    startPlace = 1;
    endPlace = 0;

    // initially, only the single start tasks is enabled
    possiblyEnabledElements = new HNSubSet();
    for (int i = 0; i < hNet.getStartTasks().size(); i++) {
      possiblyEnabledElements.add(hNet.getStartTasks().get(i));
    }
    for (int i = 0; i < size; i++) {
      outElements = marking[i].keySet().iterator();
      while (outElements.hasNext()) {
        outSubset = (HNSubSet) outElements.next();
        marking[i].put(outSubset, new Integer(0));
      }
      outElements = null;
    }
  }
  private int identifyDuplicateToFire(HNSubSet duplicates, int elementInATE) {

    HNSubSet candidateDuplicates = new HNSubSet();
    HNSubSet allElements;

    for (int i = 0; i < duplicates.size(); i++) {
      allElements = hNet.getAllElementsOutputSet(duplicates.get(i));
      for (int j = 0; j < allElements.size(); j++) {
        if (elementInATE == hNet.getDuplicatesMapping()[allElements.get(j)]) {
          candidateDuplicates.add(duplicates.get(i));
          break;
        }
      }
    }

    if (candidateDuplicates.size() <= 0) {
      candidateDuplicates = duplicates; // we can choose any of the tasks
      // because none has
      // followers in the process instance...
    }

    return candidateDuplicates.get(generator.nextInt(candidateDuplicates.size()));
  }
  private CombinationTasksToFire findBestCombination(
      CombinationTasksToFire bCombination,
      HNSet inputSet,
      int rootTask,
      CombinationTasksToFire combination,
      HNSubSet treatedTasks) {

    int task = -1;
    HNSet alreadyMarkedPlaces = null;
    HNSet temp_inputSet = null;
    HNSubSet noTokensFromTasks = null;
    HNSubSet subset = null;

    if ((bCombination.getTasks().size() == 0)
        || (bCombination.getNumberMissingTokens() > combination.getNumberMissingTokens())) {
      if (rootTask != ROOT_TASK_ID) {
        alreadyMarkedPlaces = getAlreadyMarkedPlaces(inputSet, rootTask);
        noTokensFromTasks = HNSet.getUnionSet(alreadyMarkedPlaces);
        inputSet.removeAll(alreadyMarkedPlaces);
        combination.getTasks().add(rootTask);
      }

      if (inputSet.size() == 0) {
        bCombination = combination.copy();
      } else {

        // akam: I stoppe here - 10/07/2005
        if (rootTask != ROOT_TASK_ID) {
          temp_inputSet = new HNSet();
          for (int iInputSet = 0; iInputSet < inputSet.size(); iInputSet++) {
            subset = inputSet.get(iInputSet);
            subset.removeAll(noTokensFromTasks);
            subset.removeAll(treatedTasks);
            if (subset.size() == 0) {
              combination.setTokens(combination.getNumberMissingTokens() + 1);
            } else {
              temp_inputSet.add(subset);
            }
          }
          inputSet = temp_inputSet;
        }

        for (int iInputSet = 0; iInputSet < inputSet.size(); iInputSet++) {
          subset = inputSet.get(iInputSet);
          while (subset.size() > 0) {
            task = subset.get(generator.nextInt(subset.size()));
            bCombination =
                findBestCombination(
                    bCombination,
                    inputSet.deepCopy(),
                    task,
                    combination.copy(),
                    treatedTasks.deepCopy());
            treatedTasks.add(task);
            subset.remove(task);
          }
        }
      }
    }

    return bCombination;
  }
 private void addToPossiblyEnabledElements(int element) {
   HNSubSet subset = hNet.getAllElementsOutputSet(element);
   for (int i = 0; i < subset.size(); i++) {
     possiblyEnabledElements.add(subset.get(i));
   }
 }