/**
   * Fills in oldPopulation with new individuals.
   *
   * @param oldPopulation EnhancedHeuristicsNet[] population to be filled in.
   * @return EnhancedHeuristicsNet[] population with new individuals. There are no duplicated
   *     individuals in this population.
   */
  public HeuristicsNet[] build(HeuristicsNet[] oldPopulation) {

    int size = 0;
    HNSet singleton = null;

    population = oldPopulation;

    size = population.length;

    for (int i = 0; i < size; i++) {
      // create an individual
      population[i] =
          new HeuristicsNet(
              logReader.getLogSummary().getLogEvents(),
              geneticMiningMatrices.getDuplicatesMapping(),
              geneticMiningMatrices.getReverseDuplicatesMapping());

      // create its input/output sets
      for (int j = 0; j < population[i].size(); j++) {
        population[i].setInputSet(j, buildInputSet(j));
        population[i].setOutputSet(j, buildOutputSet(j));

        if (geneticMiningMatrices.getStartMatrix().get(j) > 0) {
          // because this is the artificial START tasks....
          if (population[i].getStartTasks() == null) {
            HNSubSet startTasks = new HNSubSet();
            startTasks.add(j);
            population[i].setStartTasks(startTasks);

          } else {
            population[i].getStartTasks().add(j);
          }
          singleton = new HNSet();
          singleton.add(population[i].getAllElementsOutputSet(j));
          population[i].setOutputSet(j, singleton);
        }

        if (geneticMiningMatrices.getEndMatrix().get(j) > 0) {
          // because this is the artificial END tasks....
          if (population[i].getEndTasks() == null) {
            HNSubSet endTasks = new HNSubSet();
            endTasks.add(j);
            population[i].setEndTasks(endTasks);
          } else {
            population[i].getEndTasks().add(j);
          }
          singleton = new HNSet();
          singleton.add(population[i].getAllElementsInputSet(j));
          population[i].setInputSet(j, singleton);
        }
      }

      // generate new matrices for next individual
      geneticMiningMatrices.rebuildAllMatrices();
    }

    return population;
  }
  private int[] mapToDuplicateLabel(int[] duplicatesLabel, HNSubSet union) {

    int[] mapping = new int[union.size()];

    for (int i = 0; i < union.size(); i++) {
      mapping[i] = duplicatesLabel[union.get(i)];
    }

    return mapping;
  }