@RequestMapping("/change_password")
  public String changePassword(HttpServletRequest request) {
    Application application = ApplicationResolver.INSTANCE.getApplication(request);
    Account account = AccountResolver.INSTANCE.getAccount(request);

    if (account != null && application != null) {
      String email = account.getEmail();
      PasswordResetToken token = application.sendPasswordResetEmail(email);
      return "redirect:/change?sptoken=" + token.getValue();
    }
    return "redirect:/login?next=/change_password";
  }
  @Override
  protected ViewModel onValidSubmit(HttpServletRequest req, HttpServletResponse resp, Form form)
      throws Exception {

    // Create a new Account instance that will represent the submitted user information:
    Account account = client.instantiate(Account.class);

    String value = form.getFieldValue("email");
    if (value != null) {
      account.setEmail(value);
    }

    value = form.getFieldValue("username");
    if (value != null) {
      account.setUsername(value);
    }

    value = form.getFieldValue("password");
    if (value != null) {
      account.setPassword(value);
    }

    value = form.getFieldValue("givenName");
    account.setGivenName(value != null ? value : "UNKNOWN");

    value = form.getFieldValue("middleName");
    if (value != null) {
      account.setMiddleName(value);
    }

    value = form.getFieldValue("surname");
    account.setSurname(value != null ? value : "UNKNOWN");

    account.getCustomData().putAll(getCustomData(req, form));

    // Get the Stormpath Application instance corresponding to this web app:
    Application app = ApplicationResolver.INSTANCE.getApplication(req);

    if (preRegisterHandler != null) {
      if (!preRegisterHandler.handle(req, resp, account)) {
        return null;
      }
    }

    AccountStore accountStore = accountStoreResolver.getAccountStore(req, resp);

    if (accountStore == null) {
      // now persist the new account, and ensure our account reference points to the newly
      // created/returned instance:
      account = app.createAccount(account);
    } else {
      final Account[] accountHolder = new Account[] {account};

      accountStore.accept(
          new AccountStoreVisitorAdapter() {
            @Override
            public void visit(Directory directory) {
              Account createdAccount = directory.createAccount(accountHolder[0]);
              accountHolder[0] = createdAccount;
            }

            @Override
            public void visit(Organization organization) {
              Account createdAccount = organization.createAccount(accountHolder[0]);
              accountHolder[0] = createdAccount;
            }
          });

      account = accountHolder[0];
    }

    publishRequestEvent(new DefaultRegisteredAccountRequestEvent(req, resp, account));

    if (postRegisterHandler != null) {
      if (!postRegisterHandler.handle(req, resp, account)) {
        return null;
      }
    }

    AccountStatus status = account.getStatus();

    if (isJsonPreferred(req, resp)) {
      //noinspection unchecked
      return new DefaultViewModel(
          STORMPATH_JSON_VIEW_NAME,
          java.util.Collections.singletonMap(
              "account", accountModelFactory.toMap(account, Collections.EMPTY_LIST)));
    }

    if (status == AccountStatus.ENABLED) {
      if (autoLogin) {
        // the user does not need to verify their email address, so just assume they are
        // authenticated
        // (since they specified their password during registration):
        final AuthenticationResult result = new TransientAuthenticationResult(account);
        this.authenticationResultSaver.set(req, resp, result);
      } else {
        return new DefaultViewModel(loginUri + "?status=created").setRedirect(true);
      }
    } else if (status == AccountStatus.UNVERIFIED) {
      return new DefaultViewModel(loginUri + "?status=unverified").setRedirect(true);
    }
    return new DefaultViewModel(nextUri).setRedirect(true);
  }