@Override
  public List<CommitteeMembershipBase> getAvailableCommitteeMembersForCurrentSubmission(
      ProtocolBase protocol) {
    List<CommitteeMembershipBase> results = new ArrayList<CommitteeMembershipBase>();

    ProtocolSubmissionBase submission = protocol.getProtocolSubmission();
    submission.refreshReferenceObject("protocolOnlineReviews");
    if (LOG.isDebugEnabled()) {
      LOG.debug(
          String.format(
              "Fetching available committee members for protocol %s, submission %s",
              protocol.getProtocolNumber(), submission.getSubmissionNumber()));
    }

    List<ProtocolOnlineReviewBase> currentReviews = submission.getProtocolOnlineReviews();
    List<CommitteeMembershipBase> committeeMembers =
        getCommitteeService()
            .getAvailableMembers(submission.getCommitteeId(), submission.getScheduleId());
    // TODO: Make this better.
    for (CommitteeMembershipBase member : committeeMembers) {
      boolean found = false;
      for (ProtocolOnlineReviewBase review : currentReviews) {
        if (review.getProtocolReviewer().isProtocolReviewerFromCommitteeMembership(member)
            && review.isActive()) {
          found = true;
          break;
        }
      }
      if (!found && !isProtocolPersonnel(protocol, member)) {
        results.add(member);
      }
    }

    return results;
  }
 /*
  * this returns a list of submission numbers for a protocol.
  */
 private List<Integer> getAvailableSubmissionNumbers() {
   List<Integer> submissionNumbers = new ArrayList<Integer>();
   for (ProtocolSubmissionBase submission : getProtocol().getProtocolSubmissions()) {
     submissionNumbers.add(submission.getSubmissionNumber());
   }
   return submissionNumbers;
 }
  @Override
  public ProtocolOnlineReviewDocumentBase createAndRouteProtocolOnlineReviewDocument(
      ProtocolSubmissionBase protocolSubmission,
      ProtocolReviewer protocolReviewer,
      String documentDescription,
      String documentExplanation,
      String documentOrganizationDocumentNumber,
      String documentRouteAnnotation,
      boolean initialApproval,
      Date dateRequested,
      Date dateDue,
      String principalId) {

    ProtocolOnlineReviewDocumentBase document = null;

    try {
      if (LOG.isDebugEnabled()) {
        String protocolNumber = protocolSubmission.getProtocolNumber();
        Integer submissionNumber = protocolSubmission.getSubmissionNumber();
        LOG.debug(
            String.format(
                "Assigning online reviewer [%s] to protocol [%s].",
                protocolReviewer, protocolNumber));
        LOG.debug(
            String.format(
                "Current submission for protocol %s is %s.", protocolNumber, submissionNumber));
      }

      document =
          createProtocolOnlineReviewDocument(
              protocolSubmission,
              protocolReviewer,
              documentDescription,
              documentExplanation,
              documentOrganizationDocumentNumber,
              dateRequested,
              dateDue,
              principalId);

      documentService.routeDocument(
          document,
          "Review Requested by PI during protocol submission.",
          new ArrayList<AdHocRouteRecipient>());

      if (initialApproval) {
        documentService.approveDocument(document, "", new ArrayList<AdHocRouteRecipient>());
      }
    } catch (WorkflowException e) {
      String errorString =
          String.format(
              "WorkflowException creating new ProtocolOnlineReviewDocumentBase for reviewer %s, protocol %s",
              protocolReviewer.getPersonId(), protocolSubmission.getProtocolNumber());
      LOG.error(errorString, e);
      throw new RuntimeException(errorString, e);
    }

    return document;
  }
 private boolean isMergedToProtocol(ProtocolBase protocol, ProtocolBase amendment) {
   boolean merged = false;
   int submissionNumber =
       amendment
           .getProtocolSubmissions()
           .get(amendment.getProtocolSubmissions().size() - 1)
           .getSubmissionNumber();
   for (ProtocolSubmissionBase submission : protocol.getProtocolSubmissions()) {
     if (submissionNumber == submission.getSubmissionNumber().intValue()) {
       merged = true;
       break;
     }
   }
   return merged;
 }
  @Override
  public ProtocolReviewer createProtocolReviewer(
      String principalId,
      boolean nonEmployeeFlag,
      String reviewerTypeCode,
      ProtocolSubmissionBase protocolSubmission) {
    ProtocolReviewer reviewer = createNewProtocolReviewerInstanceHook();
    reviewer.setProtocolIdFk(protocolSubmission.getProtocolId());
    reviewer.setSubmissionIdFk(protocolSubmission.getSubmissionId());
    reviewer.setProtocolNumber(protocolSubmission.getProtocolNumber());
    reviewer.setSequenceNumber(protocolSubmission.getSequenceNumber());
    reviewer.setSubmissionNumber(protocolSubmission.getSubmissionNumber());
    if (!nonEmployeeFlag) {
      reviewer.setPersonId(principalId);
    } else {
      reviewer.setRolodexId(Integer.parseInt(principalId));
    }
    reviewer.setNonEmployeeFlag(nonEmployeeFlag);
    reviewer.setReviewerTypeCode(reviewerTypeCode);

    businessObjectService.save(reviewer);

    return reviewer;
  }
  @Override
  public void removeOnlineReviewDocument(
      String personId,
      boolean nonEmployeeFlag,
      ProtocolSubmissionBase submission,
      String annotation) {
    ProtocolOnlineReviewDocumentBase protocolOnlineReviewDocument =
        this.getProtocolOnlineReviewDocument(personId, nonEmployeeFlag, submission);

    ProtocolOnlineReviewBase submissionsProtocolOnlineReview = null;
    for (ProtocolOnlineReviewBase rev : submission.getProtocolOnlineReviews()) {
      if (rev.getProtocolOnlineReviewId()
          .equals(
              protocolOnlineReviewDocument.getProtocolOnlineReview().getProtocolOnlineReviewId())) {
        submissionsProtocolOnlineReview = rev;
        break;
      }
    }

    if (submissionsProtocolOnlineReview == null) {
      throw new IllegalStateException(
          "Could not match OnlineReview document being removed to a protocolOnlineReview in the submission.");
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(
          String.format(
              "Processing request to remove online review for (personId=%s,nonEmployeeFlag=%s) from (protocol=%s,submission=%s)",
              personId,
              nonEmployeeFlag,
              submission.getProtocol().getProtocolNumber(),
              submission.getSubmissionNumber()));
    }

    if (protocolOnlineReviewDocument != null) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            String.format(
                "Found protocolOnlineReviewDocument %s, removing it.",
                protocolOnlineReviewDocument.getDocumentNumber()));
      }
      cancelOnlineReviewDocument(protocolOnlineReviewDocument, submission, annotation);
      submissionsProtocolOnlineReview.setProtocolOnlineReviewStatusCode(
          getProtocolOLRRemovedCancelledStatusCodeHook());

      List<CommitteeScheduleMinuteBase> reviewComments =
          protocolOnlineReviewDocument.getProtocolOnlineReview().getCommitteeScheduleMinutes();
      List<CommitteeScheduleMinuteBase> deletedReviewComments =
          new ArrayList<CommitteeScheduleMinuteBase>();
      getReviewerCommentsService().deleteAllReviewComments(reviewComments, deletedReviewComments);
      getReviewerCommentsService().saveReviewComments(reviewComments, deletedReviewComments);

      getBusinessObjectService().save(submissionsProtocolOnlineReview);

    } else {
      LOG.warn(
          String.format(
              "ProtocolBase Online Review document could not be found for (personId=%s,nonEmployeeFlag=%s) from (protocol=%s,submission=%s)",
              personId,
              nonEmployeeFlag,
              submission.getProtocol().getProtocolNumber(),
              submission.getSubmissionNumber()));
    }
  }