public Future<Promotion> approve(
      AbstractBuild<?, ?> build,
      PromotionProcess promotionProcess,
      List<ParameterValue> paramValues)
      throws IOException {
    if (canApprove(promotionProcess, build)) {
      // add approval to build
      ManualApproval approval = new ManualApproval(promotionProcess.getName(), paramValues);
      build.addAction(approval);
      build.save();

      // check for promotion
      return promotionProcess.considerPromotion2(build, approval);
    }
    return null;
  }
  @Override
  public PromotionBadge isMet(PromotionProcess promotionProcess, AbstractBuild<?, ?> build) {
    List<ManualApproval> approvals = build.getActions(ManualApproval.class);

    for (ManualApproval approval : approvals) {
      if (approval.name.equals(promotionProcess.getName())) return approval.badge;
    }

    return null;
  }
  /**
   * Verifies that the currently logged in user (or anonymous) has permission to approve the
   * promotion and that the promotion has not already been approved.
   */
  public boolean canApprove(PromotionProcess promotionProcess, AbstractBuild<?, ?> build) {
    if (!getUsersAsSet().isEmpty() && !isInUsersList() && !isInGroupList()) {
      return false;
    }

    List<ManualApproval> approvals = build.getActions(ManualApproval.class);

    // For now, only allow approvals if this wasn't already approved
    for (ManualApproval approval : approvals) {
      if (approval.name.equals(promotionProcess.getName())) return false;
    }

    return true;
  }