// this method should be invoked from within the transaction wrapper that covers the request
 // processing so
 // that the db-calls in this method do not each generate new transactions. If executed from within
 // the context
 // of display rendering, this logic will be quite expensive due to the number of new transactions
 // needed.
 @Override
 public Collection<CMT> getAssignmentCommittees(
     String protocolLeadUnit, String docRouteStatus, String currentCommitteeId) {
   Collection<CMT> assignmentCommittees = new ArrayList<CMT>();
   // get the initial list of all valid committees; some of them will be filtered out by the logic
   // below
   Collection<CMT> candidateCommittees = getCandidateCommittees();
   if (CollectionUtils.isNotEmpty(candidateCommittees)) {
     if (isSaved(docRouteStatus)) {
       // Use the lead unit of the protocol to determine committees
       Set<String> unitIds = getProtocolUnitIds(protocolLeadUnit);
       for (CMT committee : candidateCommittees) {
         if (StringUtils.equalsIgnoreCase(committee.getCommitteeDocument().getDocStatusCode(), "F")
             && unitIds.contains(committee.getHomeUnit().getUnitNumber())) {
           assignmentCommittees.add(committee);
         }
       }
     } else {
       // we check the current user's authorization to assign committees
       String principalId = GlobalVariables.getUserSession().getPerson().getPrincipalId();
       for (CMT committee : candidateCommittees) {
         if (isCurrentUserAuthorizedToAssignThisCommittee(principalId, committee)
             || committee.getCommitteeId().equals(currentCommitteeId)) {
           assignmentCommittees.add(committee);
         }
       }
     }
   }
   return assignmentCommittees;
 }
  /**
   * This method returns the set of unique committees, by filtering out the committees with the same
   * committee id. It takes the committee id with the highest sequence number
   *
   * @return a collection of unique committees based on committee id and sequence number.
   */
  private Collection<CMT> getCandidateCommittees() {
    Map<String, String> criteria = new HashMap<String, String>();
    criteria.put(COMMITTEE_TYPE_CODE, getCommitteeTypeCodeHook());

    Collection<CMT> allCommittees =
        getBusinessObjectService().findMatching(getCommitteeBOClassHook(), criteria);
    HashMap<String, CMT> committeeMap = new HashMap<String, CMT>();

    CMT tmpComm = null;
    for (CMT comm : allCommittees) {
      if (FINAL_STATUS_CD.equalsIgnoreCase(comm.getCommitteeDocument().getDocStatusCode())) {
        if (committeeMap.containsKey(comm.getCommitteeId())) {
          tmpComm = committeeMap.get(comm.getCommitteeId());
          if (comm.getSequenceNumber().intValue() > tmpComm.getSequenceNumber().intValue()) {
            committeeMap.put(comm.getCommitteeId(), comm);
          }
        } else {
          committeeMap.put(comm.getCommitteeId(), comm);
        }
      }
    }

    return committeeMap.values();
  }