private String[] updateUserRoles(Role role, List<String> selectedUsers, Realm realm)
      throws Exception {
    UserDatabase userDatabase = UserDatabaseManager.getInstance().getUserDatabase(realm);
    User[] usersInRole = userDatabase.getUsersInRole(role);

    Collection<String> usersNotRemoved = new TreeSet<String>();
    for (User user : usersInRole) {
      String principalName = user.getPrincipalName();
      if (selectedUsers.contains(principalName)) {
        // role is already assigned so make sure this don't happen again
        selectedUsers.remove(principalName);
      } else {
        Role[] updatedRoles = removeRole(role, user.getRoles());
        try {
          userDatabase.updateAccount(user, user.getEmail(), user.getFullname(), updatedRoles);
        } catch (GroupsRequiredForUserException e) {
          usersNotRemoved.add(principalName);
        }
      }
    }

    for (String principalName : selectedUsers) {
      User user = userDatabase.getAccount(principalName);
      Role[] updatedRoles = addRole(role, user.getRoles());
      userDatabase.updateAccount(user, user.getEmail(), user.getFullname(), updatedRoles);
    }
    return usersNotRemoved.toArray(new String[usersNotRemoved.size()]);
  }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.struts.actions.DispatchAction#unspecified(org.apache.struts.action.ActionMapping,
   *      org.apache.struts.action.ActionForm,
   *      javax.servlet.http.HttpServletRequest,
   *      javax.servlet.http.HttpServletResponse)
   */
  public ActionForward unspecified(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {
    List<WizardActionStatus> actionStatus = new ArrayList<WizardActionStatus>();
    AbstractWizardSequence seq = getWizardSequence(request);
    String name = (String) seq.getAttribute(WebForwardResourceDetailsForm.ATTR_RESOURCE_NAME, null);
    String description =
        (String) seq.getAttribute(WebForwardResourceDetailsForm.ATTR_RESOURCE_DESCRIPTION, null);
    boolean favorite =
        ((Boolean) seq.getAttribute(WebForwardResourceDetailsForm.ATTR_FAVORITE, Boolean.FALSE))
            .booleanValue();

    int type =
        ((Integer) seq.getAttribute(WebForwardTypeSelectionForm.ATTR_TYPE, new Integer(0)))
            .intValue();
    String category = (String) seq.getAttribute(WebForwardSpecificDetailsForm.ATTR_CATEGORY, null);
    String destinationURL =
        (String) seq.getAttribute(WebForwardSpecificDetailsForm.ATTR_DESTINATION_URL, null);

    PropertyList restrictToHosts =
        ((PropertyList)
            seq.getAttribute(WebForwardSpecificDetailsForm.ATTR_RESTRICT_TO_HOSTS, null));
    String encodeing = (String) seq.getAttribute(WebForwardSpecificDetailsForm.ATTR_ENCODEING, "");

    String authenticationUsername =
        (String)
            seq.getAttribute(
                WebForwardAuthenticationDetailsForm.ATTR_AUTHENTICATION_USERNAME, null);
    String authenticationPassword =
        (String)
            seq.getAttribute(
                WebForwardAuthenticationDetailsForm.ATTR_AUTHENTICATION_PASSWORD, null);
    String preferredAuthenticationScheme =
        (String)
            seq.getAttribute(
                WebForwardAuthenticationDetailsForm.ATTR_PREFERRED_AUTHENTICATION_SCHEME, null);

    String paths = (String) seq.getAttribute(WebForwardSpecificDetailsForm.ATTR_PATHS, "");
    String hostHeader =
        (String) seq.getAttribute(WebForwardSpecificDetailsForm.ATTR_HOST_HEADER, "");
    boolean activeDNS =
        ((Boolean) seq.getAttribute(WebForwardSpecificDetailsForm.ATTR_ACTIVE_DNS, Boolean.FALSE))
            .booleanValue();

    String formParameters =
        (String) seq.getAttribute(WebForwardAuthenticationDetailsForm.ATTR_FORM_PARAMETERS, "");
    String formType =
        (String) seq.getAttribute(WebForwardAuthenticationDetailsForm.ATTR_FORM_TYPE, "");
    boolean autoStart = false; // TODO this needs to be hooked in
    User user = this.getSessionInfo(request).getUser();

    WebForward webForward = null;
    try {
      try {
        Calendar now = Calendar.getInstance();

        if (type == WebForward.TYPE_TUNNELED_SITE) {
          com.adito.webforwards.TunneledSiteWebForward sswf =
              new com.adito.webforwards.TunneledSiteWebForward(
                  user.getRealm().getRealmID(),
                  -1,
                  destinationURL,
                  name,
                  description,
                  category,
                  autoStart,
                  now,
                  now);
          webForward = WebForwardDatabaseFactory.getInstance().createWebForward(sswf);
          CoreEvent evt =
              new ResourceChangeEvent(
                      this,
                      WebForwardEventConstants.CREATE_WEB_FORWARD,
                      webForward,
                      this.getSessionInfo(request),
                      CoreEvent.STATE_SUCCESSFUL)
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_CATEGORY,
                      webForward.getCategory())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_TYPE,
                      ((WebForwardTypeItem)
                              WebForwardTypes.WEB_FORWARD_TYPES.get(webForward.getType()))
                          .getName())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL,
                      webForward.getDestinationURL());
          CoreServlet.getServlet().fireCoreEvent(evt);
        } else if (type == WebForward.TYPE_REPLACEMENT_PROXY) {
          com.adito.webforwards.ReplacementProxyWebForward spwf =
              new com.adito.webforwards.ReplacementProxyWebForward(
                  user.getRealm().getRealmID(),
                  -1,
                  destinationURL,
                  name,
                  description,
                  category,
                  authenticationUsername,
                  authenticationPassword,
                  preferredAuthenticationScheme,
                  encodeing,
                  restrictToHosts,
                  formType,
                  formParameters,
                  autoStart,
                  now,
                  now);

          AbstractAuthenticatingWebForward abstractAuthenticatingWebForward =
              (AbstractAuthenticatingWebForward)
                  WebForwardDatabaseFactory.getInstance().createWebForward(spwf);
          CoreEvent evt =
              new ResourceChangeEvent(
                      this,
                      WebForwardEventConstants.CREATE_WEB_FORWARD,
                      abstractAuthenticatingWebForward,
                      this.getSessionInfo(request),
                      CoreEvent.STATE_SUCCESSFUL)
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_CATEGORY,
                      abstractAuthenticatingWebForward.getCategory())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_TYPE,
                      ((WebForwardTypeItem)
                              WebForwardTypes.WEB_FORWARD_TYPES.get(
                                  abstractAuthenticatingWebForward.getType()))
                          .getName())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL,
                      abstractAuthenticatingWebForward.getDestinationURL())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_PREFERED_AUTH_SCHEME,
                      abstractAuthenticatingWebForward.getPreferredAuthenticationScheme())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_AUTH_USERNAME,
                      abstractAuthenticatingWebForward.getAuthenticationUsername())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_AUTH_FORM_TYPE,
                      abstractAuthenticatingWebForward.getFormType())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_REPLACEMENT_WEB_FORWARD_ENCODEING,
                      spwf.getEncoding());

          spwf.addFormParametersToEvent(
              evt, WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_AUTH_FORM_PARAMETERS);
          spwf.addRestrictToHostsToEvent(
              evt, WebForwardEventConstants.EVENT_ATTR_REPLACEMENT_WEB_FORWARD_RESTRICT_TO_HOSTS);
          CoreServlet.getServlet().fireCoreEvent(evt);
          webForward = abstractAuthenticatingWebForward;
        } else if (type == WebForward.TYPE_PATH_BASED_REVERSE_PROXY
            || type == WebForward.TYPE_HOST_BASED_REVERSE_PROXY) {
          com.adito.webforwards.ReverseProxyWebForward rpwf =
              new com.adito.webforwards.ReverseProxyWebForward(
                  user.getRealm().getRealmID(),
                  -1,
                  type,
                  destinationURL,
                  name,
                  description,
                  category,
                  authenticationUsername,
                  authenticationPassword,
                  preferredAuthenticationScheme,
                  formType,
                  formParameters,
                  paths,
                  hostHeader,
                  activeDNS,
                  autoStart,
                  now,
                  now,
                  encodeing);
          AbstractAuthenticatingWebForward abstractAuthenticatingWebForward =
              (AbstractAuthenticatingWebForward)
                  WebForwardDatabaseFactory.getInstance().createWebForward(rpwf);
          CoreEvent evt =
              new ResourceChangeEvent(
                      this,
                      WebForwardEventConstants.CREATE_WEB_FORWARD,
                      abstractAuthenticatingWebForward,
                      this.getSessionInfo(request),
                      CoreEvent.STATE_SUCCESSFUL)
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_CATEGORY,
                      abstractAuthenticatingWebForward.getCategory())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_TYPE,
                      ((WebForwardTypeItem)
                              WebForwardTypes.WEB_FORWARD_TYPES.get(
                                  abstractAuthenticatingWebForward.getType()))
                          .getName())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL,
                      abstractAuthenticatingWebForward.getDestinationURL())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_PREFERED_AUTH_SCHEME,
                      abstractAuthenticatingWebForward.getPreferredAuthenticationScheme())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_AUTH_USERNAME,
                      abstractAuthenticatingWebForward.getAuthenticationUsername())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_AUTH_FORM_TYPE,
                      abstractAuthenticatingWebForward.getFormType())
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_REVERSE_WEB_FORWARD_ACTIVE_DNS,
                      String.valueOf(rpwf.getActiveDNS()))
                  .addAttribute(
                      WebForwardEventConstants.EVENT_ATTR_REVERSE_WEB_FORWARD_HOST_HEADER,
                      rpwf.getHostHeader());

          rpwf.addPathsToEvent(evt, WebForwardEventConstants.EVENT_ATTR_REVERSE_WEB_FORWARD_PATHS);
          rpwf.addCustomHeadersToEvent(
              evt, WebForwardEventConstants.EVENT_ATTR_REVERSE_WEB_FORWARD_CUSTOM_HEADERS);
          rpwf.addFormParametersToEvent(
              evt, WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_AUTH_FORM_PARAMETERS);
          CoreServlet.getServlet().fireCoreEvent(evt);
          webForward = abstractAuthenticatingWebForward;
        }

      } catch (Exception e) {
        CoreServlet.getServlet()
            .fireCoreEvent(
                new ResourceChangeEvent(
                    this,
                    WebForwardEventConstants.CREATE_WEB_FORWARD,
                    this.getSessionInfo(request),
                    e));
        throw e;
      }
      actionStatus.add(
          new WizardActionStatus(
              WizardActionStatus.COMPLETED_OK,
              "webForwardWizard.webForwardFinish.status.profileCreated"));
    } catch (Exception e) {
      log.error("Failed to create profile.", e);
      actionStatus.add(
          new WizardActionStatus(
              WizardActionStatus.COMPLETED_WITH_ERRORS,
              "webForwardWizard.webForwardFinish.status.failedToCreateProfile",
              e.getMessage()));
    }
    // TODO do the attaching.
    if (webForward != null) {
      actionStatus.add(
          attachToPoliciesAndAddToFavorites(
              "webForwardWizard.webForwardFinish", seq, webForward, favorite, request));
    }
    ((AbstractWizardFinishForm) form).setActionStatus(actionStatus);
    return super.unspecified(mapping, form, request, response);
  }