/** edit the enabled disabled */
  @SuppressWarnings("unchecked")
  public void memberMenuEnabledDisabled() {

    GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();

    // lets see which subject we are dealing with:
    HttpServletRequest httpServletRequest = GrouperUiFilter.retrieveHttpServletRequest();
    String menuIdOfMenuTarget = httpServletRequest.getParameter("menuIdOfMenuTarget");
    if (StringUtils.isBlank(menuIdOfMenuTarget)) {
      throw new RuntimeException("Missing id of menu target");
    }
    if (!menuIdOfMenuTarget.startsWith("memberMenuButton_")) {
      throw new RuntimeException("Invalid id of menu target: '" + menuIdOfMenuTarget + "'");
    }
    String memberId = GrouperUtil.prefixOrSuffix(menuIdOfMenuTarget, "memberMenuButton_", false);

    final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();

    GrouperSession grouperSession = null;
    Group group = null;
    try {

      grouperSession = GrouperSession.start(loggedInSubject);

      Member member = MemberFinder.findByUuid(grouperSession, memberId, true);

      group = new SimpleMembershipUpdate().retrieveGroup(grouperSession);

      Membership membership =
          group.getImmediateMembership(Group.getDefaultList(), member, false, true);

      SimpleMembershipUpdateContainer simpleMembershipUpdateContainer =
          SimpleMembershipUpdateContainer.retrieveFromSession();

      GuiMember guiMember = new GuiMember(member);
      simpleMembershipUpdateContainer.setEnabledDisabledMember(guiMember);

      guiMember.setMembership(membership);

      guiResponseJs.addAction(
          GuiScreenAction.newDialogFromJsp(
              "/WEB-INF/grouperUi/templates/simpleMembershipUpdate/simpleMembershipUpdateEnabledDisabled.jsp"));

    } catch (ControllerDone cd) {
      throw cd;
    } catch (NoSessionException nse) {
      throw nse;
    } catch (Exception se) {
      throw new RuntimeException(
          "Error listing member details: " + menuIdOfMenuTarget + ", " + se.getMessage(), se);
    } finally {
      GrouperSession.stopQuietly(grouperSession);
    }
  }
 /** Convenience method to stop duplication of logic in Actions */
 public int getPageSize(HttpSession session) {
   int pageSize = 25;
   String pageSizeStr = (String) session.getAttribute("default.pagesize");
   if (pageSizeStr == null) {
     ResourceBundle mediaBundle = GrouperUiFilter.retrieveSessionMediaResourceBundle();
     if (mediaBundle != null) pageSizeStr = mediaBundle.getString("pager.pagesize.default");
   }
   if (pageSizeStr != null) {
     try {
       pageSize = Integer.parseInt(pageSizeStr);
     } catch (Exception e) {
     }
   }
   return pageSize;
 }
  /**
   * handle a click or select from the member menu
   *
   * @param httpServletRequest
   * @param httpServletResponse
   */
  @SuppressWarnings("unused")
  public void memberMenu(
      HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {

    GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();

    final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();

    GrouperSession grouperSession = null;

    Group group = null;

    try {

      grouperSession = GrouperSession.start(loggedInSubject);

      // make sure we are on the right group
      group = new SimpleMembershipUpdate().retrieveGroup(grouperSession);

    } catch (NoSessionException se) {
      throw se;
    } catch (ControllerDone cd) {
      throw cd;
    } catch (Exception se) {
      throw new RuntimeException("Error member menu: " + group + ", " + se.getMessage(), se);
    } finally {
      GrouperSession.stopQuietly(grouperSession);
    }

    String menuItemId = httpServletRequest.getParameter("menuItemId");
    String menuHtmlId = httpServletRequest.getParameter("menuHtmlId");
    // String menuRadioGroup = httpServletRequest.getParameter("menuRadioGroup");
    // String menuCheckboxChecked  = httpServletRequest.getParameter("menuCheckboxChecked");

    menuHtmlId = httpServletRequest.getParameter("menuIdOfMenuTarget");
    if (StringUtils.equals(menuItemId, "memberDetails")) {
      //        guiResponseJs.addAction(GuiScreenAction.newAlert("Menu action: menuItemId: " +
      // menuItemId
      //            + ", menuHtmlId: " + menuHtmlId));
      this.memberMenuSubjectDetails();
    } else if (StringUtils.equals(menuItemId, "enabledDisabled")) {
      this.memberMenuEnabledDisabled();
    } else {
      throw new RuntimeException("Unexpected menu id: '" + menuItemId + "'");
    }
  }
  /**
   * handle a click or select from the advanced menu
   *
   * @param httpServletRequest
   * @param httpServletResponse
   */
  public void advancedMenu(
      HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
    GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();

    final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();

    GrouperSession grouperSession = null;

    Group group = null;

    try {

      grouperSession = GrouperSession.start(loggedInSubject);

      // make sure we are on the right group
      group = new SimpleMembershipUpdate().retrieveGroup(grouperSession);

    } catch (NoSessionException se) {
      throw se;
    } catch (ControllerDone cd) {
      throw cd;
    } catch (Exception se) {
      throw new RuntimeException("Error advanced menu: " + group + ", " + se.getMessage(), se);
    } finally {
      GrouperSession.stopQuietly(grouperSession);
    }

    String menuItemId = httpServletRequest.getParameter("menuItemId");
    String menuEvent = httpServletRequest.getParameter("menuEvent");
    boolean isOnClick = StringUtils.equals("onClick", menuEvent);
    // String menuHtmlId = httpServletRequest.getParameter("menuHtmlId");
    // String menuRadioGroup = httpServletRequest.getParameter("menuRadioGroup");
    String menuCheckboxChecked = httpServletRequest.getParameter("menuCheckboxChecked");

    //    guiResponseJs.addAction(GuiScreenAction.newAlert("Menu action: menuItemId: " + menuItemId
    //        + ", menuHtmlId: " + menuHtmlId
    //        + ", menuRadioGroup: "
    //        + menuRadioGroup + ", menuCheckboxChecked: " + menuCheckboxChecked));

    if (StringUtils.equals(menuItemId, "inviteLink")) {
      guiResponseJs.addAction(
          GuiScreenAction.newScript(
              "window.location = 'grouper.html?operation=InviteExternalSubjects.inviteExternalSubject&groupId="
                  + group.getUuid()
                  + "'"));
    } else if (StringUtils.equals(menuItemId, "showGroupDetails")) {
      if (!isOnClick) {
        if (GrouperUtil.booleanValue(menuCheckboxChecked)) {
          guiResponseJs.addAction(
              GuiScreenAction.newHideShowNameToShow("simpleMembershipUpdateGroupDetails"));
        } else {
          guiResponseJs.addAction(
              GuiScreenAction.newHideShowNameToHide("simpleMembershipUpdateGroupDetails"));
        }
      }
    } else if (StringUtils.equals(menuItemId, "multiDelete")) {
      if (!isOnClick) {
        if (GrouperUtil.booleanValue(menuCheckboxChecked)) {
          guiResponseJs.addAction(
              GuiScreenAction.newHideShowNameToShow("simpleMembershipUpdateDeleteMultiple"));
        } else {
          guiResponseJs.addAction(
              GuiScreenAction.newHideShowNameToHide("simpleMembershipUpdateDeleteMultiple"));
        }
      }
    } else if (StringUtils.equals(menuItemId, "showMemberFilter")) {
      if (!isOnClick) {
        if (GrouperUtil.booleanValue(menuCheckboxChecked)) {
          guiResponseJs.addAction(
              GuiScreenAction.newHideShowNameToShow("simpleMembershipUpdateMemberFilter"));
        } else {
          guiResponseJs.addAction(
              GuiScreenAction.newHideShowNameToHide("simpleMembershipUpdateMemberFilter"));
        }
      }
    } else if (StringUtils.equals(menuItemId, "exportSubjectIds")) {
      guiResponseJs.addAction(
          GuiScreenAction.newAlertFromJsp(
              "/WEB-INF/grouperUi/templates/simpleMembershipUpdate/simpleMembershipUpdateExportSubjectIds.jsp"));
    } else if (StringUtils.equals(menuItemId, "exportAll")) {
      guiResponseJs.addAction(
          GuiScreenAction.newAlertFromJsp(
              "/WEB-INF/grouperUi/templates/simpleMembershipUpdate/simpleMembershipUpdateExportAll.jsp"));

    } else if (StringUtils.equals(menuItemId, "import")) {
      guiResponseJs.addAction(
          GuiScreenAction.newDialogFromJsp(
              "/WEB-INF/grouperUi/templates/simpleMembershipUpdate/simpleMembershipUpdateImport.jsp"));
    } else {
      throw new RuntimeException("Unexpected menu id: '" + menuItemId + "'");
    }
  }
  /** show subject details */
  @SuppressWarnings("unchecked")
  public void memberMenuSubjectDetails() {

    GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();

    // lets see which subject we are dealing with:
    HttpServletRequest httpServletRequest = GrouperUiFilter.retrieveHttpServletRequest();
    String menuIdOfMenuTarget = httpServletRequest.getParameter("menuIdOfMenuTarget");
    if (StringUtils.isBlank(menuIdOfMenuTarget)) {
      throw new RuntimeException("Missing id of menu target");
    }
    if (!menuIdOfMenuTarget.startsWith("memberMenuButton_")) {
      throw new RuntimeException("Invalid id of menu target: '" + menuIdOfMenuTarget + "'");
    }
    String memberId = GrouperUtil.prefixOrSuffix(menuIdOfMenuTarget, "memberMenuButton_", false);

    final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();

    GrouperSession grouperSession = null;

    try {

      grouperSession = GrouperSession.start(loggedInSubject);

      Member member = MemberFinder.findByUuid(grouperSession, memberId, true);
      Subject subject = member.getSubject();
      String order = null;

      try {
        order =
            GrouperUiConfig.retrieveConfig()
                .propertyValueString("subject.attributes.order." + subject.getSource().getId());
      } catch (MissingResourceException mre) {
        // thats ok, go with default
      }

      if (StringUtils.isBlank(order)) {
        Set<String> attributeNames = new LinkedHashSet<String>();
        attributeNames.add("screenLabel");
        attributeNames.addAll(GrouperUtil.nonNull(subject.getAttributes()).keySet());

        // lets add subjectId, typeName, sourceId, sourceName, memberId
        attributeNames.add("subjectId");
        attributeNames.add("name");
        attributeNames.add("description");
        attributeNames.add("typeName");
        attributeNames.add("sourceId");
        attributeNames.add("sourceName");

        order = GrouperUtil.join(attributeNames.iterator(), ',');
      }

      String[] attrNames = GrouperUtil.splitTrim(order, ",");

      SimpleMembershipUpdateContainer simpleMembershipUpdateContainer =
          SimpleMembershipUpdateContainer.retrieveFromSession();
      simpleMembershipUpdateContainer.setSubjectForDetails(subject);
      simpleMembershipUpdateContainer.getSubjectDetails().clear();

      // lookup each attribute
      for (String attrName : attrNames) {

        // sometimes group have blank attributes???
        if (StringUtils.isBlank(attrName)) {
          continue;
        }
        String attributeValue = GuiSubject.attributeValue(subject, attrName);
        simpleMembershipUpdateContainer.getSubjectDetails().put(attrName, attributeValue);
      }
      guiResponseJs.addAction(
          GuiScreenAction.newAlertFromJsp(
              "/WEB-INF/grouperUi/templates/simpleMembershipUpdate/simpleMembershipUpdateSubjectDetails.jsp"));

    } catch (ControllerDone cd) {
      throw cd;
    } catch (NoSessionException nse) {
      throw nse;
    } catch (Exception se) {
      throw new RuntimeException(
          "Error listing member details: " + menuIdOfMenuTarget + ", " + se.getMessage(), se);
    } finally {
      GrouperSession.stopQuietly(grouperSession);
    }
  }
  /**
   * make the structure of the advanced menu
   *
   * @param httpServletRequest
   * @param httpServletResponse
   */
  public void advancedMenuStructure(
      HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {

    // get the text to add to html if showing details
    GuiHideShow showGroupDetails =
        GuiHideShow.retrieveHideShow("simpleMembershipUpdateGroupDetails", true);

    // get the text to add to html if showing multi delete
    GuiHideShow showMultiDelete =
        GuiHideShow.retrieveHideShow("simpleMembershipUpdateDeleteMultiple", true);

    // get the text to add to html if showing member filter
    GuiHideShow showMemberFilter =
        GuiHideShow.retrieveHideShow("simpleMembershipUpdateMemberFilter", true);

    SimpleMembershipUpdateContainer simpleMembershipUpdateContainer =
        SimpleMembershipUpdateContainer.retrieveFromSession();

    DhtmlxMenu dhtmlxMenu = new DhtmlxMenu();

    final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();

    Group group = null;
    GrouperSession grouperSession = null;
    boolean canInviteOthers = false;
    try {

      grouperSession = GrouperSession.start(loggedInSubject);

      group = new SimpleMembershipUpdate().retrieveGroup(grouperSession);

      UIGroupPrivilegeResolver resolver =
          UIGroupPrivilegeResolverFactory.getInstance(
              grouperSession,
              GrouperUiFilter.retrieveSessionMediaResourceBundle(),
              group,
              grouperSession.getSubject());
      canInviteOthers = resolver.canInviteExternalPeople();
    } finally {
      GrouperSession.stopQuietly(grouperSession);
    }

    {
      DhtmlxMenuItem multiDeleteMenuItem = new DhtmlxMenuItem();
      multiDeleteMenuItem.setId("multiDelete");
      multiDeleteMenuItem.setType("checkbox");
      if (showMultiDelete.isShowing()) {
        multiDeleteMenuItem.setChecked(showMultiDelete.isShowing());
      }
      multiDeleteMenuItem.setText(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuDeleteMultiple());
      multiDeleteMenuItem.setTooltip(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuDeleteMultipleTooltip());
      dhtmlxMenu.addDhtmlxItem(multiDeleteMenuItem);
    }

    {
      // see if we can invite
      if (canInviteOthers
          && GrouperUiConfig.retrieveConfig()
              .propertyValueBoolean("inviteExternalPeople.link-from-lite-ui", false)) {
        DhtmlxMenuItem memberInviteMenuItem = new DhtmlxMenuItem();
        memberInviteMenuItem.setId("inviteLink");
        memberInviteMenuItem.setText(TagUtils.navResourceString("ui-lite.invite-menu"));
        memberInviteMenuItem.setTooltip(TagUtils.navResourceString("ui-lite.invite-menuTooltip"));
        // memberInviteMenuItem.setHref("grouper.html?operation=InviteExternalSubjects.inviteExternalSubject&groupId=" + group.getUuid());
        // memberInviteMenuItem.setHref("http://localhost:8091/grouper/grouperUi/appHtml/grouper.html?operation=InviteExternalSubjects.inviteExternalSubject&groupId=0e0262d9be924774914052c12f0e7fd2");
        dhtmlxMenu.addDhtmlxItem(memberInviteMenuItem);
      }
    }

    {
      DhtmlxMenuItem groupDetailsMenuItem = new DhtmlxMenuItem();
      groupDetailsMenuItem.setId("showGroupDetails");
      groupDetailsMenuItem.setType("checkbox");
      if (showGroupDetails.isShowing()) {
        groupDetailsMenuItem.setChecked(showGroupDetails.isShowing());
      }
      groupDetailsMenuItem.setText(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuShowGroupDetails());
      groupDetailsMenuItem.setTooltip(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuShowGroupDetailsTooltip());
      dhtmlxMenu.addDhtmlxItem(groupDetailsMenuItem);
    }

    {
      DhtmlxMenuItem memberFilterMenuItem = new DhtmlxMenuItem();
      memberFilterMenuItem.setId("showMemberFilter");
      memberFilterMenuItem.setType("checkbox");
      if (showMemberFilter.isShowing()) {
        memberFilterMenuItem.setChecked(showMemberFilter.isShowing());
      }
      memberFilterMenuItem.setText(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuShowMemberFilter());
      memberFilterMenuItem.setTooltip(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuShowMemberFilterTooltip());
      dhtmlxMenu.addDhtmlxItem(memberFilterMenuItem);
    }

    DhtmlxMenuItem importExportMenuItem = new DhtmlxMenuItem();
    importExportMenuItem.setId("importExport");
    importExportMenuItem.setText(
        simpleMembershipUpdateContainer.getText().getAdvancedMenuImportExport());
    importExportMenuItem.setTooltip(
        simpleMembershipUpdateContainer.getText().getAdvancedMenuImportExportTooltip());
    dhtmlxMenu.addDhtmlxItem(importExportMenuItem);

    DhtmlxMenuItem exportMenuItem = new DhtmlxMenuItem();
    exportMenuItem.setId("export");
    exportMenuItem.setText(simpleMembershipUpdateContainer.getText().getAdvancedMenuExport());
    exportMenuItem.setTooltip(
        simpleMembershipUpdateContainer.getText().getAdvancedMenuExportTooltip());
    importExportMenuItem.addDhtmlxItem(exportMenuItem);

    {
      DhtmlxMenuItem exportSubjectIdsMenuItem = new DhtmlxMenuItem();
      exportSubjectIdsMenuItem.setId("exportSubjectIds");
      exportSubjectIdsMenuItem.setText(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuExportSubjectIds());
      exportSubjectIdsMenuItem.setTooltip(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuExportSubjectIdsTooltip());
      exportMenuItem.addDhtmlxItem(exportSubjectIdsMenuItem);
    }

    {
      DhtmlxMenuItem exportAllMenuItem = new DhtmlxMenuItem();
      exportAllMenuItem.setId("exportAll");
      exportAllMenuItem.setText(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuExportAll());
      exportAllMenuItem.setTooltip(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuExportAllTooltip());
      exportMenuItem.addDhtmlxItem(exportAllMenuItem);
    }

    {
      DhtmlxMenuItem importMenuItem = new DhtmlxMenuItem();
      importMenuItem.setId("import");
      importMenuItem.setText(simpleMembershipUpdateContainer.getText().getAdvancedMenuImport());
      importMenuItem.setTooltip(
          simpleMembershipUpdateContainer.getText().getAdvancedMenuImportTooltip());
      importExportMenuItem.addDhtmlxItem(importMenuItem);
    }

    GrouperUiUtils.printToScreen(
        "<?xml version=\"1.0\"?>\n" + dhtmlxMenu.toXml(), HttpContentType.TEXT_XML, false, false);
    throw new ControllerDone();
  }
  /**
   * Makes HttpSession and GrouperSession available to subclasses Also handles pageSize parameter
   * and times how long is spent in an action
   */
  public ActionForward execute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    GrouperSession grouperSession =
        (GrouperSession)
            request.getSession().getAttribute("edu.intenet2.middleware.grouper.ui.GrouperSession");
    // if(grouperSession == null && !"/populateIndex.do".equals(request.getServletPath())) return
    // mapping.findForward("Index");

    ModuleConfig modConfig = (ModuleConfig) request.getAttribute("org.apache.struts.action.MODULE");
    String modulePrefix = modConfig.getPrefix();
    if (modulePrefix == null) modulePrefix = "";
    request.setAttribute("modulePrefix", modulePrefix);
    HttpSession session = request.getSession();
    String pageSize = request.getParameter("pageSize");
    if (pageSize != null && pageSize.length() > 0) {
      session.setAttribute("default.pagesize", pageSize);
    }

    DynaActionForm dummyForm = (DynaActionForm) form;
    if (dummyForm != null) {
      try {
        dummyForm.set("pageSize", "" + getPageSize(session));
      } catch (Exception e) {
        // Ok so form doesn't care about pageSize
        // let's just ignore it
      }
    }
    isWheelGroupMember(session);
    String wheelGroupAction = request.getParameter("wheelGroupAction");
    if (!isEmpty(wheelGroupAction)) doWheelGroupStuff(wheelGroupAction, session);
    UIThreadLocal.replace(
        "isActiveWheelGroupMember", new Boolean(isActiveWheelGroupMember(session)));

    if (grouperSession != null) {
      if (isWheelGroupMember(session)) {
        grouperSession.setConsiderIfWheelMember(isActiveWheelGroupMember(session));
      } else {
        // we'll set this back to the default
        grouperSession.setConsiderIfWheelMember(true);
      }
    }

    if (form != null) request.setAttribute("grouperForm", form);
    Object sessionMessage = session.getAttribute("sessionMessage");
    if (isEmpty(request.getAttribute("message")) && !isEmpty(sessionMessage)) {
      request.setAttribute("message", sessionMessage);
      session.removeAttribute("sessionMessage");
    }
    request.setAttribute("linkBrowseMode", getLinkBrowseMode(session));
    Date before = new Date();
    ActionForward forward = null;
    try {
      if (isEmpty(wheelGroupAction)) {

        forward =
            grouperTransactionExecute(mapping, form, request, response, session, grouperSession);

      } else
        forward =
            new ActionForward(
                GrouperUiFilter.retrieveSessionMediaResourceBundle().getString("admin.browse.path"),
                true);
    } catch (GrouperDAOException e) {
      Throwable cause = e.getCause();

      Throwable causeCause = cause == null ? null : cause.getCause();

      Throwable causeCauseCause = causeCause == null ? null : causeCause.getCause();

      HookVeto hookVeto = (cause instanceof HookVeto) ? (HookVeto) cause : null;

      hookVeto =
          ((hookVeto == null) && (causeCause instanceof HookVeto))
              ? (HookVeto) causeCause
              : hookVeto;

      hookVeto =
          ((hookVeto == null) && (causeCauseCause instanceof HookVeto))
              ? (HookVeto) causeCauseCause
              : hookVeto;

      if (hookVeto != null) {
        Message.addVetoMessageToScreen(request, hookVeto);
      } else if (!(cause instanceof UnrecoverableErrorException)) {
        LOG.error(NavExceptionHelper.toLog(cause));
        cause = new UnrecoverableErrorException(cause);
      }
      if (cause instanceof UnrecoverableErrorException) {
        NavExceptionHelper neh = getExceptionHelper(session);
        String msg = neh.getMessage((UnrecoverableErrorException) cause);
        request.setAttribute("seriousError", msg);
      }
      forward = mapping.findForward("ErrorPage");
    }
    Date after = new Date();
    long diff = after.getTime() - before.getTime();
    String url = request.getServletPath();
    Long ms = (Long) request.getAttribute("timingsMS");
    long mss = 0;
    if (ms != null) mss = ms.longValue();
    if (diff > 25) {
      request.setAttribute("timingsClass", this.getClass().getName());
      request.setAttribute("timingsMS", new Long(diff + mss));
    }
    if (forward != null && forward.getRedirect() && !isEmpty(request.getAttribute("message"))) {
      try {
        session.setAttribute("sessionMessage", request.getAttribute("message"));
      } catch (IllegalStateException e) {
      }
    }

    if (Boolean.TRUE.equals(request.getAttribute("loggedOut"))) {
      return forward;
    }
    try {
      GrouperHelper.fixSessionFields((Map) session.getAttribute("fieldList"));
    } catch (SchemaException e) {
      LOG.error(e);
    }
    String advSearch = request.getParameter("advancedSearch");
    try {
      session.getAttribute("");
    } catch (Exception e) {
      return forward;
    }
    if (!isEmpty(advSearch)) {
      setAdvancedSearchMode("true".equals(advSearch), session);
    }
    request.setAttribute("isAdvancedSearch", getAdvancedSearchMode(session));
    return forward;
  }
  public ActionForward grouperExecute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response,
      HttpSession session,
      GrouperSession grouperSession)
      throws Exception {
    Class sortOverrideClass = Group.class;
    NavExceptionHelper neh = getExceptionHelper(session);
    DynaActionForm subjectForm = (DynaActionForm) form;
    if ("true".equals(request.getParameter("changeMode")))
      PopulateSearchSubjectsAction.initMode(session);
    session.setAttribute("subtitle", "subject.action.show-summary");
    if (isEmpty(subjectForm.get("callerPageId"))) {
      if (isEmpty(subjectForm.get("subjectId"))) {
        LOG.info("Restoring lastSubjectSummaryForm");
        restoreDynaFormBean(session, subjectForm, "lastSubjectSummaryForm");
      } else {
        LOG.info("Saving lastSubjectSummaryForm");
        saveDynaFormBean(session, subjectForm, "lastSubjectSummaryForm");
        saveAsCallerPage(request, subjectForm);
      }
    }
    saveAsCallerPage(request, subjectForm);

    String listField = (String) subjectForm.get("listField");
    String membershipField = "members";

    if (!isEmpty(listField)) {
      membershipField = listField;
    }
    Field mField = null;
    try {
      mField = FieldFinder.find(membershipField, true);
    } catch (SchemaException e) {
      LOG.error("Could not find Field: " + membershipField, e);
      if ("members".equals(membershipField)) {
        LOG.fatal("Built in field: members, missing");
        throw new UnrecoverableErrorException(e);
      } else {
        mField = FieldFinder.find("members", true);
        request.setAttribute(
            "message", new Message("error.subject-summary.missing-field", listField, true));
      }
    }

    subjectForm.set("contextSubject", "true");
    String subjectId = (String) subjectForm.get("subjectId");
    String subjectType = (String) subjectForm.get("subjectType");
    String subjectSource = (String) subjectForm.get("sourceId");
    if (isEmpty(subjectId) || isEmpty(subjectType) || isEmpty(subjectSource)) {
      String msg =
          neh.missingParameters(
              subjectId, "subjectId", subjectType, "subjectType", subjectSource, "sourceId");
      LOG.error(msg);
      if (doRedirectToCaller(subjectForm)) {
        session.setAttribute(
            "sessionMessage", new Message("error.subject-summary.missing-parameter", true));
        return redirectToCaller(subjectForm);
      }
      throw new UnrecoverableErrorException("error.subject-summary.missing-parameter");
    }
    Subject subject = null;
    try {
      subject = SubjectFinder.findById(subjectId, subjectType, subjectSource, true);
    } catch (Exception e) {
      LOG.error(e);
      if (e instanceof SubjectNotFoundException) {
        subject = new UnresolvableSubject(subjectId, subjectType, subjectSource);
        addMessage(
            new Message(
                "error.subject.unresolvable", new String[] {subjectId, subjectSource}, true),
            request);
      } else {

        String contextError = "error.subject-summary.subject.exception";
        session.setAttribute("sessionMessage", new Message(neh.key(e), contextError, true));
        if (doRedirectToCaller(subjectForm)) return redirectToCaller(subjectForm);
        throw new UnrecoverableErrorException(contextError, e);
      }
    }
    Map subjectMap = GrouperHelper.subject2Map(subject);
    request.setAttribute("subject", subjectMap);

    String order = null;
    try {
      order =
          GrouperUiFilter.retrieveSessionMediaResourceBundle()
              .getString("subject.attributes.order." + subject.getSource().getId());
      request.setAttribute("subjectAttributeNames", order.split(","));
    } catch (Exception e) {
      // No order specified, so go with all, in whatever order they come
      List extendedAttr = new ArrayList(GrouperUtil.nonNull(subject.getAttributes()).keySet());
      extendedAttr.add("subjectType");
      extendedAttr.add("id");
      request.setAttribute("subjectAttributeNames", extendedAttr);
    }
    String membershipListScope = (String) subjectForm.get("membershipListScope");

    if ("any-access".equals(membershipListScope)) {
      if ("false".equals(request.getParameter("advancedSearch"))) {
        membershipListScope = null;
      } else {
        request.setAttribute("fromSubjectSummary", Boolean.TRUE);

        session.setAttribute("groupSearchSubject", subject);
        session.setAttribute("groupSearchSubjectMap", subjectMap);
        return mapping.findForward(FORWARD_GroupSearch);
      }
    }
    if (":all:imm:eff:access:naming:".indexOf(":" + membershipListScope + ":") == -1) {
      membershipListScope = (String) session.getAttribute("subjectMembershipListScope");
    }
    if (membershipListScope == null) membershipListScope = "imm";
    session.setAttribute("subjectMembershipListScope", membershipListScope);
    subjectForm.set("membershipListScope", membershipListScope);

    String accessPriv = (String) subjectForm.get("accessPriv");
    if (isEmpty(accessPriv)) accessPriv = (String) session.getAttribute("subjectSummaryAccessPriv");
    if (isEmpty(accessPriv)) accessPriv = "read";
    session.setAttribute("subjectSummaryAccessPriv", accessPriv);
    subjectForm.set("accessPriv", accessPriv);

    String namingPriv = (String) subjectForm.get("namingPriv");
    if (isEmpty(namingPriv)) namingPriv = (String) session.getAttribute("subjectSummaryNamingPriv");
    if (isEmpty(namingPriv)) namingPriv = "create";
    session.setAttribute("subjectSummaryNamingPriv", namingPriv);
    subjectForm.set("namingPriv", namingPriv);
    // Retrieve the membership according to scope selected by user
    Member member = null;
    try {
      member = MemberFinder.findBySubject(grouperSession, subject, true);
      if (member == null) {
        throw new MemberNotFoundException("Unresolvable subject is also not a Member");
      }
    } catch (Exception e) {
      LOG.error(e);
      if (doRedirectToCaller(subjectForm)) {
        session.setAttribute(
            "sessionMessage", new Message("error.subject-summary.member.exception", true));
        return redirectToCaller(subjectForm);
      }
      throw new UnrecoverableErrorException("error.subject-summary.member.exception", e);
    }
    Set subjectScopes = null;
    List subjectScopeMaps = null;
    Map listViews = new HashMap();
    listViews.put("titleKey", "subject.summary.memberships");
    listViews.put("noResultsKey", "subject.list-membership.none");
    listViews.put("view", "whereSubjectsAreMembers");
    // listViews.put("itemView","whereIsMemberLink");
    listViews.put("itemView", "subjectSummary");
    listViews.put("headerView", "genericListHeader");
    listViews.put("footerView", "genericListFooter");

    if ("imm".equals(membershipListScope)) {
      subjectScopes = member.getImmediateMemberships(mField);
      listViews.put("noResultsKey", "subject.list-membership.imm.none");
    } else if ("eff".equals(membershipListScope)) {
      if (membershipField.equals("members")) {
        subjectScopes = member.getMemberships();
        subjectScopes.removeAll(member.getImmediateMemberships());

      } else {
        subjectScopes = member.getEffectiveMemberships(mField);
        listViews.put("noResultsKey", "subject.list-membership.all.none");
      }
      if ("members".equals(membershipField)) {
        listViews.put("noResultsKey", "subject.list-membership.eff.none");
      } else {
        listViews.put("noResultsKey", "subject.list-membership.custom.eff.none");
      }

    } else if ("all".equals(membershipListScope)) {
      subjectScopes = member.getMemberships(mField);
      listViews.put("noResultsKey", "subject.list-membership.all.none");
    } else if ("access".equals(membershipListScope)) {

      subjectScopes = GrouperHelper.getGroupsOrStemsWhereMemberHasPriv(member, accessPriv);

      // filter out groups where the subject can't see privs
      removeObjectsNotAllowedToSeePrivs(subjectScopes);

      subjectScopeMaps =
          GrouperHelper.subjects2SubjectPrivilegeMaps(
              grouperSession, subjectScopes, subject, accessPriv);
      listViews.put("titleKey", "subject.summary.access-privs");
      listViews.put("noResultsKey", "subject.list-access.none");
      listViews.put("view", "subjectSummaryPrivileges");
      listViews.put("itemView", "subjectSummaryPrivilege");
    } else {
      sortOverrideClass = Stem.class;
      subjectScopes = GrouperHelper.getGroupsOrStemsWhereMemberHasPriv(member, namingPriv);

      // filter out stems where the subject can't see privs
      removeObjectsNotAllowedToSeePrivs(subjectScopes);

      subjectScopeMaps =
          GrouperHelper.subjects2SubjectPrivilegeMaps(
              grouperSession, subjectScopes, subject, namingPriv);
      listViews.put("titleKey", "subject.summary.naming-privs");
      listViews.put("noResultsKey", "subject.list-naming.none");
      listViews.put("view", "subjectSummaryPrivileges");
      listViews.put("itemView", "subjectSummaryPrivilege");
    }
    request.setAttribute("scopeListData", listViews);
    if (subjectScopeMaps == null) {
      Map countMap = new HashMap();
      Map sources = new HashMap();
      List uniqueSubjectScopes =
          GrouperHelper.getOneMembershipPerSubjectOrGroup(
              subjectScopes, "subject", countMap, sources, 0);
      subjectScopeMaps = GrouperHelper.memberships2Maps(grouperSession, uniqueSubjectScopes);
      GrouperHelper.setMembershipCountPerSubjectOrGroup(subjectScopeMaps, "subject", countMap);
    }
    // This is a hack to force sorting by Group/Stem rather than Subject - which is generally what
    // happens with Memberships
    // DefaultComparatorImpl has been updated to read the TheadLocal
    UIThreadLocal.put("GrouperComparatorHelperOverrideClass", sortOverrideClass);
    subjectScopeMaps = sort(subjectScopeMaps, request, "subjectSummary", -1, null);
    UIThreadLocal.replace("GrouperComparatorHelperOverrideClass", null);
    String startStr = (String) subjectForm.get("start");
    if (startStr == null || "".equals(startStr)) startStr = "0";

    int start = Integer.parseInt(startStr);
    int pageSize = getPageSize(session);
    int end = start + pageSize;
    if (end > subjectScopeMaps.size()) end = subjectScopeMaps.size();
    CollectionPager pager =
        new CollectionPager(
            null, subjectScopeMaps, subjectScopeMaps.size(), null, start, null, pageSize);

    if (!isEmpty(listField)) pager.setParam("listField", listField);
    pager.setParam("subjectId", subjectId);
    pager.setParam("subjectType", subjectType);
    pager.setParam("sourceId", subjectSource);
    pager.setParam("returnTo", subjectForm.get("returnTo"));
    pager.setParam("returnToLinkKey", subjectForm.get("returnToLinkKey"));
    pager.setTarget(mapping.getPath());
    request.setAttribute("pager", pager);
    request.setAttribute("linkParams", pager.getParams().clone());
    request.setAttribute("listFieldParams", pager.getParams().clone());

    Map saveParams = new HashMap();
    saveParams.put("subjectId", subject.getId());
    saveParams.put("subjectType", subject.getType().getName());
    saveParams.put("sourceId", subject.getSource().getId());
    saveParams.put("callerPageId", request.getAttribute("thisPageId"));
    request.setAttribute("saveParams", saveParams);

    if (subjectType.equals("group")) {
      List lists = GrouperHelper.getReadableListFieldsForGroup(grouperSession, subjectId);
      if (!lists.isEmpty()) request.setAttribute("listFields", lists);
    }

    List memberOfListFields = GrouperHelper.getListFieldsForSubject(grouperSession, subject);
    if (memberOfListFields.size() > 0) {
      request.setAttribute("memberOfListFields", memberOfListFields);
    }

    Collection accessPrivs =
        GrouperHelper.getGroupPrivsWithLabels(GrouperUiFilter.retrieveSessionNavResourceBundle());
    Collection namingPrivs =
        GrouperHelper.getStemPrivsWithLabels(GrouperUiFilter.retrieveSessionNavResourceBundle());
    request.setAttribute("allAccessPrivs", accessPrivs);
    request.setAttribute("allNamingPrivs", namingPrivs);

    return mapping.findForward(FORWARD_SubjectSummary);
  }