public void populatePermissions(DocumentConfigurationViewForm form) {

    DocumentType docType = form.getDocumentType();
    Map<String, List<Role>> permRoles = new HashMap<String, List<Role>>();
    // loop over the document hierarchy
    Set<String> seenDocumentPermissions = new HashSet<String>();
    while (docType != null) {
      String documentTypeName = docType.getName();
      Predicate p =
          and(
              equal("active", "Y"),
              equal(
                  "attributes[" + KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME + "]",
                  docType.getName()));
      List<Permission> perms =
          getPermissionService()
              .findPermissions(QueryByCriteria.Builder.fromPredicates(p))
              .getResults();
      for (Permission perm : perms) {
        PermissionBo permBo = PermissionBo.from(perm);
        List<String> roleIds =
            getPermissionService().getRoleIdsForPermission(perm.getNamespaceCode(), perm.getName());
        if (!roleIds.isEmpty()) {
          permRoles.put(perm.getId(), getRoleService().getRoles(roleIds));
        }
        for (String attributeName : permBo.getDetails().keySet()) {
          addAttributeLabel(form, attributeName);
        }
      }
      // show the section if the current document or permissions exist
      if (perms.size() > 0 || documentTypeName.equals(form.getDocumentTypeName())) {
        ArrayList<PermissionForDisplay> dispPerms =
            new ArrayList<PermissionForDisplay>(perms.size());
        for (Permission perm : perms) {
          PermissionBo permBo = PermissionBo.from(perm);
          if (permBo.getDetails().size() == 1) { // only the document type
            // this is a document type-specific permission, check if seen earlier
            if (seenDocumentPermissions.contains(
                perm.getTemplate().getNamespaceCode() + "|" + perm.getTemplate().getName())) {
              dispPerms.add(new PermissionForDisplay(permBo, true));
            } else {
              dispPerms.add(new PermissionForDisplay(permBo, false));
              seenDocumentPermissions.add(
                  perm.getTemplate().getNamespaceCode() + "|" + perm.getTemplate().getName());
            }
          } else {
            // other attributes, can't determine whether this is overridden at another level
            dispPerms.add(new PermissionForDisplay(permBo, false));
          }
        }
        form.setPermissionsForDocumentType(documentTypeName, dispPerms);
        form.addDocumentType(documentTypeName);
      }
      docType = docType.getParentDocType();
    }

    form.setPermissionRoles(permRoles);
  }
  protected void populateRoutingExceptionResponsibility(DocumentConfigurationViewForm form) {
    DocumentType docType = form.getDocumentType();
    List<ResponsibilityForDisplay> responsibilities = new ArrayList<ResponsibilityForDisplay>();
    while (docType != null) {
      QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
      Predicate p =
          and(
              equal("template.namespaceCode", KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE),
              equal(
                  "template.name", KewApiConstants.EXCEPTION_ROUTING_RESPONSIBILITY_TEMPLATE_NAME),
              equal("active", "Y"),
              equal("attributes[documentTypeName]", docType.getName()));
      builder.setPredicates(p);
      List<Responsibility> resps =
          getResponsibilityService().findResponsibilities(builder.build()).getResults();

      for (Responsibility r : resps) {
        if (responsibilities.isEmpty()) {
          responsibilities.add(new ResponsibilityForDisplay(r, false));
        } else {
          responsibilities.add(new ResponsibilityForDisplay(r, true));
        }
      }
      docType = docType.getParentDocType();
    }
    form.setExceptionResponsibilities(responsibilities);
    for (ResponsibilityForDisplay responsibility : responsibilities) {
      List<String> roleIds =
          getResponsibilityService().getRoleIdsForResponsibility(responsibility.getResp().getId());
      if (!roleIds.isEmpty()) {
        form.getResponsibilityRoles()
            .put(responsibility.getResponsibilityId(), getRoleService().getRoles(roleIds));
      }
    }
  }
  @SuppressWarnings("unchecked")
  public void populateRoutingResponsibilities(DocumentConfigurationViewForm form) {
    // pull all the responsibilities
    // merge the data and attach to route levels
    // pull the route levels and store on form
    // List<RouteNode> routeNodes = getRouteNodeService().getFlattenedNodes(form.getDocumentType(),
    // true);
    Map<String, List<Role>> respToRoleMap = new HashMap<String, List<Role>>();
    List<ProcessDefinitionBo> processes =
        (List<ProcessDefinitionBo>) form.getDocumentType().getProcesses();
    if (!(processes.isEmpty())) {
      RouteNode rootNode = processes.get(0).getInitialRouteNode();
      LinkedHashMap<String, RouteNode> routeNodeMap = new LinkedHashMap<String, RouteNode>();
      flattenRouteNodes(rootNode, routeNodeMap);

      form.setRouteNodes(new ArrayList<RouteNode>(routeNodeMap.values()));
      // pull all the responsibilities and store into a map for use by the JSP

      // FILTER TO THE "Review" template only
      // pull responsibility roles
      DocumentType docType = form.getDocumentType();
      Set<Responsibility> responsibilities = new HashSet<Responsibility>();
      Map<String, List<ResponsibilityForDisplay>> nodeToRespMap =
          new LinkedHashMap<String, List<ResponsibilityForDisplay>>();
      while (docType != null) {
        QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
        Predicate p =
            and(
                equal("template.namespaceCode", KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE),
                equal("template.name", KewApiConstants.DEFAULT_RESPONSIBILITY_TEMPLATE_NAME),
                equal("active", "Y"),
                equal("attributes[documentTypeName]", docType.getName()));
        builder.setPredicates(p);
        List<Responsibility> resps =
            getResponsibilityService().findResponsibilities(builder.build()).getResults();

        for (Responsibility r : resps) {
          String routeNodeName =
              r.getAttributes().get(KimConstants.AttributeConstants.ROUTE_NODE_NAME);
          if (StringUtils.isNotBlank(routeNodeName)) {
            if (!nodeToRespMap.containsKey(routeNodeName)) {
              nodeToRespMap.put(routeNodeName, new ArrayList<ResponsibilityForDisplay>());
              nodeToRespMap.get(routeNodeName).add(new ResponsibilityForDisplay(r, false));
            } else {
              // check if the responsibility in the existing list is for the current document
              // if so, OK to add.  Otherwise, a lower level document has overridden this
              // responsibility (since we are walking up the hierarchy
              if (nodeToRespMap
                  .get(routeNodeName)
                  .get(0)
                  .getDetails()
                  .get(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME)
                  .equals(docType.getName())) {
                nodeToRespMap.get(routeNodeName).add(new ResponsibilityForDisplay(r, false));
              } else { // doc type name did not match, mark as overridden
                nodeToRespMap.get(routeNodeName).add(new ResponsibilityForDisplay(r, true));
              }
            }
            responsibilities.add(r);
          }
        }
        docType = docType.getParentDocType();
      }
      form.setResponsibilityMap(nodeToRespMap);

      for (Responsibility responsibility : responsibilities) {
        List<String> roleIds =
            getResponsibilityService().getRoleIdsForResponsibility(responsibility.getId());
        if (!roleIds.isEmpty()) {
          respToRoleMap.put(responsibility.getId(), getRoleService().getRoles(roleIds));
        }
      }
    }
    form.setResponsibilityRoles(respToRoleMap);
  }