@Override
  protected String processRegisterUserRequest(
      final String referer,
      final RegisterForm form,
      final BindingResult bindingResult,
      final Model model,
      final HttpServletRequest request,
      final HttpServletResponse response,
      final RedirectAttributes redirectModel)
      throws CMSItemNotFoundException {
    if (bindingResult.hasErrors()) {
      model.addAttribute(form);
      model.addAttribute(new LoginForm());
      model.addAttribute(new GuestForm());
      GlobalMessages.addErrorMessage(model, "form.global.error");
      final Breadcrumb loginBreadcrumbEntry =
          new Breadcrumb(
              "#",
              getMessageSource()
                  .getMessage("header.link.login", null, getI18nService().getCurrentLocale()),
              null);
      model.addAttribute("breadcrumbs", Collections.singletonList(loginBreadcrumbEntry));

      return handleRegistrationError(model);
    }

    final RegisterData data = new RegisterData();
    data.setFirstName(form.getFirstName());
    data.setLastName(form.getLastName());
    data.setLogin(form.getEmail());
    data.setPassword(form.getPwd());
    data.setTitleCode(form.getTitleCode());
    data.setMobileNumber(form.getMobileNumber());
    try {
      getCustomerFacade().register(data);
      getAutoLoginStrategy().login(form.getEmail().toLowerCase(), form.getPwd(), request, response);

      GlobalMessages.addFlashMessage(
          redirectModel,
          GlobalMessages.CONF_MESSAGES_HOLDER,
          "registration.confirmation.message.title");
    } catch (final DuplicateUidException e) {
      LOG.warn("registration failed: " + e);
      model.addAttribute(form);
      model.addAttribute(new LoginForm());
      model.addAttribute(new GuestForm());
      GlobalMessages.addErrorMessage(model, "form.global.error");
      bindingResult.rejectValue("email", "registration.error.account.exists.title");

      return handleRegistrationError(model);
    }

    return REDIRECT_PREFIX + getSuccessRedirect(request, response);
  }
  @RequestMapping(method = RequestMethod.GET)
  public String get(
      final Model model, final HttpServletRequest request, final HttpServletResponse response)
      throws CMSItemNotFoundException {
    // Check for CMS Page where label or id is like /page
    final ContentPageModel pageForRequest = getContentPageForRequest(request);
    if (pageForRequest != null) {
      storeCmsPageInModel(model, pageForRequest);
      setUpMetaDataForContentPage(model, pageForRequest);
      model.addAttribute(
          WebConstants.BREADCRUMBS_KEY,
          contentPageBreadcrumbBuilder.getBreadcrumbs(pageForRequest));
      return getViewForPage(pageForRequest);
    }

    // No page found - display the notFound page with error from controller
    storeCmsPageInModel(model, getContentPageForLabelOrId(ERROR_CMS_PAGE));
    setUpMetaDataForContentPage(model, getContentPageForLabelOrId(ERROR_CMS_PAGE));

    model.addAttribute(
        WebConstants.MODEL_KEY_ADDITIONAL_BREADCRUMB,
        resourceBreadcrumbBuilder.getBreadcrumbs("breadcrumb.not.found"));
    GlobalMessages.addErrorMessage(model, "system.error.page.not.found");

    response.setStatus(HttpServletResponse.SC_NOT_FOUND);

    return ControllerConstants.Views.Pages.Error.ErrorNotFoundPage;
  }
 protected String errorUpdatingEmail(final Model model) throws CMSItemNotFoundException {
   GlobalMessages.addErrorMessage(model, "form.global.error");
   storeCmsPageInModel(model, getContentPageForLabelOrId(UPDATE_EMAIL_CMS_PAGE));
   setUpMetaDataForContentPage(model, getContentPageForLabelOrId(UPDATE_EMAIL_CMS_PAGE));
   model.addAttribute(
       "breadcrumbs", accountBreadcrumbBuilder.getBreadcrumbs("text.account.profile"));
   return getViewForPage(model);
 }
  @RequestMapping(value = "/update-profile", method = RequestMethod.POST)
  @RequireHardLogIn
  public String updateProfile(
      final UpdateProfileForm updateProfileForm,
      final BindingResult bindingResult,
      final Model model,
      final RedirectAttributes redirectAttributes)
      throws CMSItemNotFoundException {
    getProfileValidator().validate(updateProfileForm, bindingResult);

    String returnAction = ControllerConstants.Views.Pages.Account.AccountProfileEditPage;
    final CustomerData currentCustomerData = customerFacade.getCurrentCustomer();
    final CustomerData customerData = new CustomerData();
    customerData.setTitleCode(updateProfileForm.getTitleCode());
    customerData.setFirstName(updateProfileForm.getFirstName());
    customerData.setLastName(updateProfileForm.getLastName());
    customerData.setUid(currentCustomerData.getUid());
    customerData.setDisplayUid(currentCustomerData.getDisplayUid());

    model.addAttribute("titleData", userFacade.getTitles());

    if (bindingResult.hasErrors()) {
      GlobalMessages.addErrorMessage(model, "form.global.error");
    } else {
      try {
        customerFacade.updateProfile(customerData);
        GlobalMessages.addFlashMessage(
            redirectAttributes,
            GlobalMessages.CONF_MESSAGES_HOLDER,
            "text.account.profile.confirmationUpdated",
            null);
        returnAction = REDIRECT_TO_PROFILE_PAGE;
      } catch (final DuplicateUidException e) {
        bindingResult.rejectValue("email", "registration.error.account.exists.title");
        GlobalMessages.addErrorMessage(model, "form.global.error");
      }
    }

    storeCmsPageInModel(model, getContentPageForLabelOrId(PROFILE_CMS_PAGE));
    setUpMetaDataForContentPage(model, getContentPageForLabelOrId(PROFILE_CMS_PAGE));
    model.addAttribute(
        "breadcrumbs", accountBreadcrumbBuilder.getBreadcrumbs("text.account.profile"));
    return returnAction;
  }
  @RequestMapping(value = "/update-password", method = RequestMethod.POST)
  @RequireHardLogIn
  public String updatePassword(
      final UpdatePasswordForm updatePasswordForm,
      final BindingResult bindingResult,
      final Model model,
      final RedirectAttributes redirectAttributes)
      throws CMSItemNotFoundException {
    getPasswordValidator().validate(updatePasswordForm, bindingResult);
    if (!bindingResult.hasErrors()) {
      if (updatePasswordForm.getNewPassword().equals(updatePasswordForm.getCheckNewPassword())) {
        try {
          customerFacade.changePassword(
              updatePasswordForm.getCurrentPassword(), updatePasswordForm.getNewPassword());
        } catch (final PasswordMismatchException localException) {
          bindingResult.rejectValue(
              "currentPassword",
              "profile.currentPassword.invalid",
              new Object[] {},
              "profile.currentPassword.invalid");
        }
      } else {
        bindingResult.rejectValue(
            "checkNewPassword",
            "validation.checkPwd.equals",
            new Object[] {},
            "validation.checkPwd.equals");
      }
    }

    if (bindingResult.hasErrors()) {
      GlobalMessages.addErrorMessage(model, "form.global.error");
      storeCmsPageInModel(model, getContentPageForLabelOrId(UPDATE_PASSWORD_CMS_PAGE));
      setUpMetaDataForContentPage(model, getContentPageForLabelOrId(UPDATE_PASSWORD_CMS_PAGE));

      model.addAttribute(
          "breadcrumbs",
          accountBreadcrumbBuilder.getBreadcrumbs("text.account.profile.updatePasswordForm"));
      return getViewForPage(model);
    } else {
      GlobalMessages.addFlashMessage(
          redirectAttributes,
          GlobalMessages.CONF_MESSAGES_HOLDER,
          "text.account.confirmation.password.updated",
          null);
      return REDIRECT_TO_PROFILE_PAGE;
    }
  }
  @RequestMapping(
      value = "/edit-address/" + ADDRESS_CODE_PATH_VARIABLE_PATTERN,
      method = RequestMethod.POST)
  @RequireHardLogIn
  public String editAddress(
      final AddressForm addressForm,
      final BindingResult bindingResult,
      final Model model,
      final RedirectAttributes redirectModel)
      throws CMSItemNotFoundException {
    getAddressValidator().validate(addressForm, bindingResult);
    if (bindingResult.hasErrors()) {
      GlobalMessages.addErrorMessage(model, "form.global.error");
      storeCmsPageInModel(model, getContentPageForLabelOrId(ADD_EDIT_ADDRESS_CMS_PAGE));
      setUpMetaDataForContentPage(model, getContentPageForLabelOrId(ADD_EDIT_ADDRESS_CMS_PAGE));
      setUpAddressFormAfterError(addressForm, model);
      return getViewForPage(model);
    }

    model.addAttribute("metaRobots", "noindex,nofollow");

    final AddressData newAddress = new AddressData();
    newAddress.setId(addressForm.getAddressId());
    newAddress.setTitleCode(addressForm.getTitleCode());
    newAddress.setFirstName(addressForm.getFirstName());
    newAddress.setLastName(addressForm.getLastName());
    newAddress.setLine1(addressForm.getLine1());
    newAddress.setLine2(addressForm.getLine2());
    newAddress.setTown(addressForm.getTownCity());
    newAddress.setPostalCode(addressForm.getPostcode());
    newAddress.setBillingAddress(false);
    newAddress.setShippingAddress(true);
    newAddress.setVisibleInAddressBook(true);
    newAddress.setCountry(getI18NFacade().getCountryForIsocode(addressForm.getCountryIso()));

    if (addressForm.getRegionIso() != null && !StringUtils.isEmpty(addressForm.getRegionIso())) {
      newAddress.setRegion(
          getI18NFacade().getRegion(addressForm.getCountryIso(), addressForm.getRegionIso()));
    }

    if (Boolean.TRUE.equals(addressForm.getDefaultAddress())
        || userFacade.getAddressBook().size() <= 1) {
      newAddress.setDefaultAddress(true);
      newAddress.setVisibleInAddressBook(true);
    }

    final AddressVerificationResult<AddressVerificationDecision> verificationResult =
        getAddressVerificationFacade().verifyAddressData(newAddress);
    final boolean addressRequiresReview =
        getAddressVerificationResultHandler()
            .handleResult(
                verificationResult,
                newAddress,
                model,
                redirectModel,
                bindingResult,
                getAddressVerificationFacade().isCustomerAllowedToIgnoreAddressSuggestions(),
                "checkout.multi.address.updated");

    if (addressRequiresReview) {
      model.addAttribute(
          "regions", getI18NFacade().getRegionsForCountryIso(addressForm.getCountryIso()));
      model.addAttribute("country", addressForm.getCountryIso());
      model.addAttribute("edit", Boolean.TRUE);
      storeCmsPageInModel(model, getContentPageForLabelOrId(ADD_EDIT_ADDRESS_CMS_PAGE));
      setUpMetaDataForContentPage(model, getContentPageForLabelOrId(ADD_EDIT_ADDRESS_CMS_PAGE));
      return getViewForPage(model);
    }

    userFacade.editAddress(newAddress);

    return REDIRECT_TO_ADDRESS_BOOK_PAGE;
  }
 /**
  * Prepares the view to display an error message
  *
  * @throws CMSItemNotFoundException
  */
 protected void prepareErrorMessage(final Model model, final String page)
     throws CMSItemNotFoundException {
   GlobalMessages.addErrorMessage(model, "form.global.error");
   storeCmsPageInModel(model, getContentPageForLabelOrId(page));
   setUpMetaDataForContentPage(model, getContentPageForLabelOrId(page));
 }
  @RequestMapping(value = "/response", method = RequestMethod.POST)
  @RequireHardLogIn
  public String doHandleSopResponse(
      final HttpServletRequest request,
      @Valid final SopPaymentDetailsForm sopPaymentDetailsForm,
      final BindingResult bindingResult,
      final Model model,
      final RedirectAttributes redirectAttributes)
      throws CMSItemNotFoundException {
    final Map<String, String> resultMap = getRequestParameterMap(request);

    final boolean savePaymentInfo =
        sopPaymentDetailsForm.isSavePaymentInfo()
            || getCheckoutCustomerStrategy().isAnonymousCheckout();
    final PaymentSubscriptionResultData paymentSubscriptionResultData =
        this.getPaymentFacade().completeSopCreateSubscription(resultMap, savePaymentInfo);

    if (paymentSubscriptionResultData.isSuccess()
        && paymentSubscriptionResultData.getStoredCard() != null
        && StringUtils.isNotBlank(
            paymentSubscriptionResultData.getStoredCard().getSubscriptionId())) {
      final CCPaymentInfoData newPaymentSubscription =
          paymentSubscriptionResultData.getStoredCard();

      if (getUserFacade().getCCPaymentInfos(true).size() <= 1) {
        getUserFacade().setDefaultPaymentInfo(newPaymentSubscription);
      }
      getCheckoutFacade().setPaymentDetails(newPaymentSubscription.getId());
    } else if ((paymentSubscriptionResultData.getDecision() != null
            && paymentSubscriptionResultData.getDecision().equalsIgnoreCase("error"))
        || (paymentSubscriptionResultData.getErrors() != null
            && !paymentSubscriptionResultData.getErrors().isEmpty())) {
      // Have SOP errors that we can display

      setupAddPaymentPage(model);

      // Build up the SOP form data and render page containing form
      try {
        setupSilentOrderPostPage(sopPaymentDetailsForm, model);
      } catch (final Exception e) {
        LOG.error("Failed to build beginCreateSubscription request", e);
        GlobalMessages.addErrorMessage(
            model, "checkout.multi.paymentMethod.addPaymentDetails.generalError");
        return enterStep(model, redirectAttributes);
      }

      if (paymentSubscriptionResultData.getErrors() != null
          && !paymentSubscriptionResultData.getErrors().isEmpty()) {
        GlobalMessages.addErrorMessage(model, "checkout.error.paymentethod.formentry.invalid");
        // Add in specific errors for invalid fields
        for (final PaymentErrorField paymentErrorField :
            paymentSubscriptionResultData.getErrors().values()) {
          if (paymentErrorField.isMissing()) {
            bindingResult.rejectValue(
                paymentErrorField.getName(),
                "checkout.error.paymentethod.formentry.sop.missing." + paymentErrorField.getName(),
                "Please enter a value for this field");
          }
          if (paymentErrorField.isInvalid()) {
            bindingResult.rejectValue(
                paymentErrorField.getName(),
                "checkout.error.paymentethod.formentry.sop.invalid." + paymentErrorField.getName(),
                "This value is invalid for this field");
          }
        }
      } else if (paymentSubscriptionResultData.getDecision() != null
          && paymentSubscriptionResultData.getDecision().equalsIgnoreCase("error")) {
        LOG.error(
            "Failed to create subscription. Error occurred while contacting external payment services.");
        GlobalMessages.addErrorMessage(
            model, "checkout.multi.paymentMethod.addPaymentDetails.generalError");
      }

      return ControllerConstants.Views.Pages.MultiStepCheckout.SilentOrderPostPage;
    } else {
      // SOP ERROR!
      LOG.error("Failed to create subscription.  Please check the log files for more information");
      return REDIRECT_URL_ERROR
          + "/?decision="
          + paymentSubscriptionResultData.getDecision()
          + "&reasonCode="
          + paymentSubscriptionResultData.getResultCode();
    }

    return getCheckoutStep().nextStep();
  }