@Override
  public List<String> getAssociateModules() {

    Set<String> modules = new HashSet<String>();
    Collection<String> parameters =
        this.parameterService.getParameterValuesAsString(
            Constants.PARAMETER_MODULE_QUESTIONNAIRE,
            Constants.PARAMETER_COMPONENT_PERMISSION,
            PARAM_NAME);
    for (String permission : parameters) {
      String[] params = permission.split(":");
      boolean unitAuthCheck =
          unitAuthorizationService.hasPermission(
              globalVariableService.getUserSession().getPerson().getPrincipalId(),
              params[1],
              params[0]);
      if (unitAuthCheck && !modules.contains(permissionModuleMap.get(permission))) {
        modules.add(permissionModuleMap.get(permission));
      }
    }
    return new ArrayList<String>(modules);
  }
  @Transactional
  @RequestMapping(
      value = "/proposalDevelopment",
      params = {"methodToCall=printForms"})
  public ModelAndView printForms(
      @ModelAttribute("KualiForm") ProposalDevelopmentDocumentForm form,
      HttpServletResponse response)
      throws Exception {
    ProposalDevelopmentDocument proposalDevelopmentDocument = form.getProposalDevelopmentDocument();

    proposalDevelopmentDocumentViewAuthorizer.initializeDocumentAuthorizerIfNecessary(
        form.getProposalDevelopmentDocument());

    if (!((ProposalDevelopmentDocumentAuthorizer)
            proposalDevelopmentDocumentViewAuthorizer.getDocumentAuthorizer())
        .isAuthorizedToPrint(
            proposalDevelopmentDocument, globalVariableService.getUserSession().getPerson())) {
      throw new AuthorizationException(
          globalVariableService.getUserSession().getPrincipalName(), "printForms", "Proposal");
    }

    if (proposalDevelopmentDocument.getDevelopmentProposal().getSelectedS2sOppForms().isEmpty()) {
      getGlobalVariableService()
          .getMessageMap()
          .putError("noKey", ERROR_NO_GRANTS_GOV_FORM_SELECTED);
      return getModelAndViewService().getModelAndView(form);
    }
    FormPrintResult formPrintResult = getFormPrintService().printForm(proposalDevelopmentDocument);

    setValidationErrorMessage(formPrintResult.getErrors());
    KcFile attachmentDataSource = formPrintResult.getFile();
    if (((attachmentDataSource == null
                || attachmentDataSource.getData() == null
                || attachmentDataSource.getData().length == 0)
            && !proposalDevelopmentDocument.getDevelopmentProposal().getGrantsGovSelectFlag())
        || CollectionUtils.isNotEmpty(formPrintResult.getErrors())) {
      boolean grantsGovErrorExists =
          copyAuditErrorsToPage(Constants.GRANTSGOV_ERRORS, "grantsGovFormValidationErrors");
      if (grantsGovErrorExists) {
        getGlobalVariableService()
            .getMessageMap()
            .putError(
                "grantsGovFormValidationErrors",
                KeyConstants.VALIDATTION_ERRORS_BEFORE_GRANTS_GOV_SUBMISSION);
      }
      proposalDevelopmentDocument.getDevelopmentProposal().setGrantsGovSelectFlag(false);
      return getModelAndViewService().getModelAndView(form);
    }
    if (proposalDevelopmentDocument.getDevelopmentProposal().getGrantsGovSelectFlag()) {
      File grantsGovXmlDirectoryFile =
          getS2sSubmissionService().getGrantsGovSavedFile(proposalDevelopmentDocument);
      byte[] bytes = new byte[(int) grantsGovXmlDirectoryFile.length()];
      FileInputStream fileInputStream = new FileInputStream(grantsGovXmlDirectoryFile);
      fileInputStream.read(bytes);
      int size = bytes.length;
      try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(size)) {
        outputStream.write(bytes);
        ControllerFileUtils.streamOutputToResponse(
            response,
            outputStream,
            "binary/octet-stream",
            grantsGovXmlDirectoryFile.getName(),
            size);
        response.flushBuffer();
      }
      proposalDevelopmentDocument.getDevelopmentProposal().setGrantsGovSelectFlag(false);
      return getModelAndViewService().getModelAndView(form);
    }

    ControllerFileUtils.streamToResponse(attachmentDataSource, response);
    return getModelAndViewService().getModelAndView(form);
  }
  @Transactional
  @RequestMapping(
      value = "/proposalDevelopment",
      params = {"methodToCall=refresh", "refreshCaller=S2sOpportunity-LookupView"})
  public ModelAndView refresh(
      @ModelAttribute("KualiForm") ProposalDevelopmentDocumentForm form,
      BindingResult result,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    ProposalDevelopmentDocument document = form.getProposalDevelopmentDocument();
    DevelopmentProposal proposal = document.getDevelopmentProposal();
    if (form.getNewS2sOpportunity() != null
        && StringUtils.isNotEmpty(form.getNewS2sOpportunity().getOpportunityId())) {

      proposal.setS2sOpportunity(form.getNewS2sOpportunity());
      proposal.getS2sOpportunity().setDevelopmentProposal(proposal);

      // Set default S2S Submission Type
      if (StringUtils.isBlank(form.getNewS2sOpportunity().getS2sSubmissionTypeCode())) {
        String defaultS2sSubmissionTypeCode =
            getProposalTypeService().getDefaultSubmissionTypeCode(proposal.getProposalTypeCode());
        proposal.getS2sOpportunity().setS2sSubmissionTypeCode(defaultS2sSubmissionTypeCode);
        getDataObjectService()
            .wrap(proposal.getS2sOpportunity())
            .fetchRelationship("s2sSubmissionType");
      }

      final String opportunityTitle = form.getNewS2sOpportunity().getOpportunityTitle();
      String trimmedTitle =
          StringUtils.substring(
              opportunityTitle, 0, ProposalDevelopmentConstants.S2sConstants.OPP_TITLE_MAX_LENGTH);
      // Set Opportunity Title and Opportunity ID in the Sponsor & Program Information section
      proposal.setProgramAnnouncementTitle(trimmedTitle);
      proposal.setCfdaNumber(form.getNewS2sOpportunity().getCfdaNumber());
      proposal.setProgramAnnouncementNumber(form.getNewS2sOpportunity().getOpportunityId());
      form.setNewS2sOpportunity(new S2sOpportunity());
    }

    S2sOpportunity s2sOpportunity = proposal.getS2sOpportunity();

    try {
      if (s2sOpportunity != null && s2sOpportunity.getSchemaUrl() != null) {
        List<String> missingMandatoryForms =
            s2sSubmissionService.setMandatoryForms(proposal, s2sOpportunity);

        if (!CollectionUtils.isEmpty(missingMandatoryForms)) {
          globalVariableService
              .getMessageMap()
              .putError(
                  Constants.NO_FIELD,
                  KeyConstants.ERROR_IF_OPPORTUNITY_ID_IS_INVALID,
                  s2sOpportunity.getOpportunityId(),
                  StringUtils.join(missingMandatoryForms, ","));
          proposal.setS2sOpportunity(null);
        }
      }
    } catch (S2sCommunicationException ex) {
      if (ex.getErrorKey().equals(KeyConstants.ERROR_GRANTSGOV_NO_FORM_ELEMENT)) {
        ex.setMessage(s2sOpportunity.getOpportunityId());
      }
      globalVariableService
          .getMessageMap()
          .putError(Constants.NO_FIELD, ex.getErrorKey(), ex.getMessageWithParams());
      proposal.setS2sOpportunity(new S2sOpportunity());
    }
    super.save(form, result, request, response);
    return getRefreshControllerService().refresh(form);
  }