@Override
  public Set<String> getEditModes(Document document, Person user, Set<String> currentEditModes) {
    Set<String> editModes = new HashSet<>();

    ProposalDevelopmentDocument proposalDoc = (ProposalDevelopmentDocument) document;
    DevelopmentProposal developmentProposal = proposalDoc.getDevelopmentProposal();
    String proposalNbr = developmentProposal.getProposalNumber();

    // The getEditMode() method is invoked when a proposal is accessed for creation and when it
    // is accessed for modification.  New proposals under creation don't have a proposal number.
    // For a new proposal, we have to know if the user has the permission to create a proposal.
    // For a current proposal, we have to know if the user the permission to modify or view the
    // proposal.

    if (proposalNbr == null) {
      if (isAuthorizedToCreate(document, user)) {
        editModes.add(AuthorizationConstants.EditMode.FULL_ENTRY);
        setPermissions(user, proposalDoc, editModes);
      } else {
        editModes.add(AuthorizationConstants.EditMode.UNVIEWABLE);
      }
    } else {
      if (canEdit(document, user)) {
        editModes.add(AuthorizationConstants.EditMode.FULL_ENTRY);
        setPermissions(user, proposalDoc, editModes);
      } else if (isAuthorizedToView(document, user)) {
        editModes.add(AuthorizationConstants.EditMode.VIEW_ONLY);
        setPermissions(user, proposalDoc, editModes);
      } else {
        editModes.add(AuthorizationConstants.EditMode.UNVIEWABLE);
      }
    }

    return editModes;
  }
  protected boolean isAuthorizedToModify(Document document, Person user) {
    DocumentRequestAuthorizationCache documentRequestAuthorizationCache =
        getDocumentRequestAuthorizationCache(document);

    final String resultCacheKey = buildPermissionCacheKey(document, user, IS_AUTHORIZED_TO_MODIFY);
    if (documentRequestAuthorizationCache.hasPermissionResult(resultCacheKey)) {
      return documentRequestAuthorizationCache.getPermissionResult(resultCacheKey);
    }

    final ProposalDevelopmentDocument pdDocument = ((ProposalDevelopmentDocument) document);
    final DevelopmentProposal proposal = pdDocument.getDevelopmentProposal();

    if (!isEditableState(proposal.getProposalStateTypeCode())) {
      return false;
    }

    final String proposalNbr = proposal.getProposalNumber();

    boolean hasPermission;
    if (proposalNbr == null) {
      hasPermission = hasPermissionByOwnedByUnit(document, user);
    } else {
      /*
       * After the initial save, the proposal can only be modified if it is not in workflow
       * and the user has the require permission.
       */

      final boolean hasBeenRejected =
          ProposalState.REVISIONS_REQUESTED.equals(proposal.getProposalStateTypeCode());

      hasPermission =
          !pdDocument.isViewOnly()
              && getKcAuthorizationService()
                  .hasPermission(
                      user.getPrincipalId(), pdDocument, PermissionConstants.MODIFY_PROPOSAL)
              && (!getKcWorkflowService().isInWorkflow(document) || hasBeenRejected)
              && !proposal.getSubmitFlag();
    }

    if (proposal.isChild() && hasPermission) {
      final Document parent = proposal.getParent().getDocument();
      final String parentResultCacheKey =
          buildPermissionCacheKey(parent, user, IS_AUTHORIZED_TO_MODIFY);
      documentRequestAuthorizationCache.getPermissionResultCache().remove(parentResultCacheKey);
      hasPermission = isAuthorizedToModify(parent, user);
    }

    documentRequestAuthorizationCache.addPermissionResult(resultCacheKey, hasPermission);

    return hasPermission;
  }