/**
   * Add Software to a Project.
   *
   * @param projectId
   * @param newSoftwareRequest
   * @throws ManagementException
   */
  public Software addProjectSoftware(String projectId, Software newSoftwareRequest)
      throws ManagementException {
    // Throw exception - empty Id
    checkProjectId(projectId);

    // Throw exception - empty Software
    checkSoftware(newSoftwareRequest);

    // Container Project must exist
    Project project = this.mgmService.getProject(projectId);
    checkContainerProject(project);

    // Generate unique ProjectHome Id
    if (newSoftwareRequest.getId() == null || newSoftwareRequest.getId().isEmpty()) {
      newSoftwareRequest.setId(UUID.randomUUID().toString());
    }

    // Throw exception - empty Software name
    if (newSoftwareRequest.getName() == null || newSoftwareRequest.getName().isEmpty()) {
      throw new ManagementException(
          ERROR_CODE_ENTITY_ILLEGAL_PARAMETER, "Software name cannot be empty.", null);
    }

    if (newSoftwareRequest.getVersion() == null || newSoftwareRequest.getVersion().isEmpty()) {
      newSoftwareRequest.setVersion("1.0.0");
    }

    // Throw exception - Software with same Id or name exists
    for (Iterator<Software> softwareItor = project.getSoftware().iterator();
        softwareItor.hasNext(); ) {
      Software currSoftware = softwareItor.next();

      if (newSoftwareRequest.getId().equals(currSoftware.getId())) {
        throw new ManagementException(
            ERROR_CODE_ENTITY_EXIST, "Software with same Id already exists.", null);
      }

      if (newSoftwareRequest.getName().equals(currSoftware.getName())
          && newSoftwareRequest.getVersion().equals(currSoftware.getVersion())) {
        throw new ManagementException(
            ERROR_CODE_ENTITY_EXIST,
            "Software with same name and same version already exists.",
            null);
      }
    }

    project.addSoftware(newSoftwareRequest);

    return newSoftwareRequest;
  }
  /**
   * Get Software list in a Project.
   *
   * @param projectId
   * @return
   * @throws ManagementException
   */
  public List<Software> getProjectSoftware(String projectId) throws ManagementException {
    // Throw exception - empty Id
    checkProjectId(projectId);

    // Container Project must exist
    Project project = this.mgmService.getProject(projectId);
    checkContainerProject(project);

    List<Software> softwareList = project.getSoftware();

    List<Software> resultSoftwareList = new ArrayList<Software>();
    resultSoftwareList.addAll(softwareList);

    return resultSoftwareList;
  }
  /**
   * Delete Software from a Project.
   *
   * @param projectId
   * @param softwareId
   * @return
   * @throws ManagementException
   */
  public boolean deleteProjectSoftware(String projectId, String softwareId)
      throws ManagementException {
    // Throw exception - empty Id
    checkProjectId(projectId);
    checkSoftwareId(softwareId);

    // Find Project
    Project project = this.mgmService.getProject(projectId);
    checkContainerProject(project);

    // Find Software
    Software softwareToDelete = getProjectSoftware(projectId, softwareId);
    checkSoftwareNotFound(softwareToDelete);

    // Delete Software from Project.
    return project.deleteSoftware(softwareToDelete);
  }
  /**
   * Get Software.
   *
   * @param projectId
   * @param softwareId
   * @return
   * @throws ManagementException
   */
  public Software getProjectSoftware(String projectId, String softwareId)
      throws ManagementException {
    // Throw exception - empty Id
    checkProjectId(projectId);
    checkSoftwareId(softwareId);

    // Container Project must exist
    Project project = this.mgmService.getProject(projectId);
    checkContainerProject(project);

    Software resultSoftware = null;

    // Iterate all Software in a Project. Find the Software with matching Id.
    for (Iterator<Software> softwareItor = project.getSoftware().iterator();
        softwareItor.hasNext(); ) {
      Software currSoftware = softwareItor.next();
      if (softwareId.equals(currSoftware.getId())) {
        resultSoftware = currSoftware;
        break;
      }
    }

    return resultSoftware;
  }