/**
   * Processes the datasets.
   *
   * @param args optional arguments (not-null, can be empty)
   */
  @Override
  public void processDataSets(String[] args) {
    String signature = CLASS_NAME + ".processDataSets()";
    LoggingWrapperUtility.logEntrance(logger, signature, null, null);

    // 1. Select the utility.
    DataSetUtility utility = null;
    for (DataSetUtility curUtility : utilities) {
      if (curUtility.getName().equalsIgnoreCase(utilityName)) {
        utility = curUtility;
        break;
      }
    }
    if (utility == null) {
      logger.log(Level.INFO, "Unknown utility: {0}", utilityName);
      StringBuilder sb = new StringBuilder("The following utilities are available: ");
      boolean first = true;
      for (DataSetUtility curUtility : utilities) {
        if (!first) {
          sb.append(", ");
        }
        first = false;
        sb.append(curUtility.getName());
      }
      logger.log(Level.INFO, sb.toString());
      return;
    }

    // 2. Select datasets for processing.
    List<DataSetInfo> dataSets =
        Helper.selectDataSets(dataSetSelector, startDataSet, endDataSet, logger);

    if (dataSets == null) {
      return;
    }

    // 3. Parse arguments
    List<String> utilityArgs = new ArrayList<String>();
    Map<String, String> utilityOptions = new HashMap<String, String>();

    for (int i = 0; i < args.length; i++) {
      String arg = args[i];
      if (arg.charAt(0) != '-') {
        utilityArgs.add(arg);
      } else {
        if (i == args.length - 1) {
          logger.log(Level.INFO, "The option {0} does not specify its value", arg);
          return;
        }
        utilityOptions.put(arg, args[i + 1]);
        i++;
      }
    }

    // 4. Run the utility
    utility.run(dataSets, utilityArgs, utilityOptions);
    LoggingWrapperUtility.logExit(logger, signature, null);
  }
  /**
   * Deletes the responsible person with the specified responsible person id.
   *
   * @param responsiblePersonId the id of the responsible person.
   * @throws ProjectMilestoneManagementException If there are any errors during the execution of
   *     this method
   * @since 1.1
   */
  @Transactional
  public void deleteResponsiblePerson(long responsiblePersonId)
      throws ProjectMilestoneManagementException {
    final String signature = CLASS_NAME + ".delete(long responsiblePersonId)";
    final Date entranceTimestamp = new Date();
    // Log entrance
    LoggingWrapperUtility.logEntrance(
        logger,
        signature,
        new String[] {"responsiblePersonId"},
        new Object[] {responsiblePersonId},
        true,
        Level.DEBUG);

    try {
      // Get the entity
      ResponsiblePerson person =
          (ResponsiblePerson) getSession().get(ResponsiblePerson.class, responsiblePersonId);

      if (person == null) {
        // throw not found exception
        throw new EntityNotFoundException(
            "The entity is not found with id[" + responsiblePersonId + "]");
      }
      // Delete entity
      getSession().delete(person);

      // Log exit
      LoggingWrapperUtility.logExit(logger, signature, null, entranceTimestamp);
    } catch (EntityNotFoundException e) {
      throw LoggingWrapperUtility.logException(logger, signature, e, true, Level.ERROR);
    } catch (HibernateException e) {
      throw LoggingWrapperUtility.logException(
          logger,
          signature,
          new ProjectMilestoneManagementException(
              "HibernateException occurs while accessing to db", e),
          true,
          Level.ERROR);
    }
  }
  /**
   * This method gets all responsible people for the given project ID. If none found, returns an
   * empty list.
   *
   * <p>Updates in version 1.1 - removes the reference to DataProvider and
   * DirectProjectMetadataService. Use native hibernate query to get the copilots and managers.
   *
   * @param projectId the ID of the direct project
   * @return the responsible people
   * @throws ProjectMilestoneManagementException If there are any errors during the execution of
   *     this method
   */
  @Transactional(readOnly = true)
  public List<ResponsiblePerson> getAllResponsiblePeople(long projectId)
      throws ProjectMilestoneManagementException {
    final String signature = CLASS_NAME + ".getAllResponsiblePeople(long projectId)";
    final Date entranceTimestamp = new Date();
    // Log entrance
    LoggingWrapperUtility.logEntrance(
        logger, signature, new String[] {"projectId"}, new Object[] {projectId}, true, Level.DEBUG);

    try {

      // Create list for responsible people:
      List<ResponsiblePerson> people = new ArrayList<ResponsiblePerson>();
      Set<Long> duplicationChecking = new HashSet<Long>();

      List copilotList =
          getSession()
              .getNamedQuery(GET_COPILOTS_FOR_PROJECT)
              .setParameter(DIRECT_PROJECT_ID_PARAM, projectId)
              .list();

      for (Object o : copilotList) {
        ResponsiblePerson p = (ResponsiblePerson) o;
        if (!duplicationChecking.contains(p.getUserId())) {
          people.add(p);
          duplicationChecking.add(p.getUserId());
        }
      }

      List managersList =
          sessionFactory
              .getCurrentSession()
              .getNamedQuery(GET_MANAGERS_FOR_PROJECT)
              .setParameter(DIRECT_PROJECT_ID_PARAM, projectId)
              .list();

      for (Object o : managersList) {
        ResponsiblePerson p = (ResponsiblePerson) o;
        if (!duplicationChecking.contains(p.getUserId())) {
          people.add(p);
          duplicationChecking.add(p.getUserId());
        }
      }

      // update all the responsible person id to 0, because they are using for looking up
      for (ResponsiblePerson p : people) {
        p.setId(0);
      }

      // Log exit
      LoggingWrapperUtility.logExit(logger, signature, new Object[] {people}, entranceTimestamp);

      // Return people
      return people;
    } catch (NumberFormatException e) {
      throw LoggingWrapperUtility.logException(
          logger,
          signature,
          new ProjectMilestoneManagementException(
              "NumberFormatException occurs while parsing long to string", e),
          true,
          Level.ERROR);
    } catch (Exception e) {
      throw LoggingWrapperUtility.logException(
          logger,
          signature,
          new ProjectMilestoneManagementException(
              "Exception occurs while getting all ResponsiblePeople", e),
          true,
          Level.ERROR);
    }
  }