@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;
  }
 @Override
 public void cancelOnlineReviews(ProtocolSubmissionBase submission, String annotation) {
   // get the online reviews, loop through them and finalize them if necessary.
   for (ProtocolOnlineReviewBase review : submission.getProtocolOnlineReviews()) {
     cancelOnlineReviewDocument(review.getProtocolOnlineReviewDocument(), submission, annotation);
   }
 }
 @Override
 public void moveOnlineReviews(
     ProtocolSubmissionBase submission, ProtocolSubmissionBase newSubmission) {
   newSubmission.setProtocolOnlineReviews(new ArrayList<ProtocolOnlineReviewBase>());
   for (ProtocolOnlineReviewBase review : submission.getProtocolOnlineReviews()) {
     review.setProtocol(newSubmission.getProtocol());
     review.setProtocolId(newSubmission.getProtocol().getProtocolId());
     review.setSubmissionIdFk(newSubmission.getSubmissionId());
     if (CollectionUtils.isNotEmpty(review.getCommitteeScheduleMinutes())) {
       for (CommitteeScheduleMinuteBase comment : review.getCommitteeScheduleMinutes()) {
         comment.setProtocolIdFk(review.getProtocolId());
         comment.setScheduleIdFk(newSubmission.getScheduleIdFk());
       }
     }
     newSubmission.getProtocolOnlineReviews().add(review);
   }
 }
 @Override
 public void finalizeOnlineReviews(ProtocolSubmissionBase submission, String annotation) {
   // get the online reviews, loop through them and finalize them if necessary.
   for (ProtocolOnlineReviewBase review : submission.getProtocolOnlineReviews()) {
     //
     // review.addActionPerformed("Finalize:"+review.getProtocolOnlineReviewDocument().getDocumentHeader().getWorkflowDocument().getStatus().getCode()+":"+review.getProtocolOnlineReviewStatusCode());
     finalizeOnlineReviewDocument(
         review.getProtocolOnlineReviewDocument(), submission, annotation);
   }
 }
  @Override
  public boolean isProtocolReviewer(
      String personId, boolean nonEmployeeFlag, ProtocolSubmissionBase protocolSubmission) {
    boolean isReviewer = false;

    if (protocolSubmission != null) {
      for (ProtocolOnlineReviewBase review : protocolSubmission.getProtocolOnlineReviews()) {
        if (review.getProtocolReviewer().isPersonIdProtocolReviewer(personId, nonEmployeeFlag)
            && review.isActive()) {
          isReviewer = true;
          break;
        }
      }
    }

    return isReviewer;
  }
  @Override
  public List<ProtocolOnlineReviewBase> getProtocolReviews(Long submissionId) {
    List<ProtocolOnlineReviewBase> reviews = new ArrayList<ProtocolOnlineReviewBase>();

    ProtocolSubmissionBase submission =
        getBusinessObjectService()
            .findBySinglePrimaryKey(getProtocolSubmissionBOClassHook(), submissionId);
    if (submission != null) {
      for (ProtocolOnlineReviewBase review : submission.getProtocolOnlineReviews()) {
        if (review.isActive()) {
          reviews.add(review);
        }
      }
    }

    return reviews;
  }
  @Override
  public ProtocolReviewer getProtocolReviewer(
      String personId, boolean nonEmployeeFlag, ProtocolSubmissionBase protocolSubmission) {
    ProtocolReviewer protocolReviewer = null;

    if (protocolSubmission != null) {
      for (ProtocolOnlineReviewBase protocolOnlineReview :
          protocolSubmission.getProtocolOnlineReviews()) {
        if (protocolOnlineReview
                .getProtocolReviewer()
                .isPersonIdProtocolReviewer(personId, nonEmployeeFlag)
            && protocolOnlineReview.isActive()) {
          protocolReviewer = protocolOnlineReview.getProtocolReviewer();
          break;
        }
      }
    }

    return protocolReviewer;
  }
  @Override
  public ProtocolOnlineReviewDocumentBase getProtocolOnlineReviewDocument(
      String personId, boolean nonEmployeeFlag, ProtocolSubmissionBase protocolSubmission) {
    ProtocolOnlineReviewDocumentBase protocolOnlineReviewDocument = null;

    if (protocolSubmission != null) {
      for (ProtocolOnlineReviewBase protocolOnlineReview :
          protocolSubmission.getProtocolOnlineReviews()) {
        if (protocolOnlineReview
                .getProtocolReviewer()
                .isPersonIdProtocolReviewer(personId, nonEmployeeFlag)
            && protocolOnlineReview.isActive()) {
          try {
            protocolOnlineReviewDocument =
                (ProtocolOnlineReviewDocumentBase)
                    getDocumentService()
                        .getByDocumentHeaderId(
                            protocolOnlineReview
                                .getProtocolOnlineReviewDocument()
                                .getDocumentNumber());
          } catch (WorkflowException e) {
            if (LOG.isDebugEnabled()) {
              String errorMessage =
                  String.format(
                      "WorkflowException encountered while looking up document number %s for ProtocolOnlineReviewDocumentBase associated with (submissionId=%s,personId=%s,nonEmployeeFlag=%s",
                      protocolOnlineReview.getProtocolOnlineReviewDocument().getDocumentNumber(),
                      protocolSubmission.getSubmissionId(),
                      personId,
                      nonEmployeeFlag);

              LOG.error(errorMessage, e);
              throw new RuntimeException(errorMessage, e);
            }
          }
        }
      }
    }

    return protocolOnlineReviewDocument;
  }
  @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()));
    }
  }