private void getCustomerOptions(
      Model model, Customer customer, MerchantStore store, Language language) throws Exception {

    Map<Long, CustomerOption> options = new HashMap<Long, CustomerOption>();
    // get options
    List<CustomerOptionSet> optionSet = customerOptionSetService.listByStore(store, language);
    if (!CollectionUtils.isEmpty(optionSet)) {

      CustomerOptionPopulator optionPopulator = new CustomerOptionPopulator();

      Set<CustomerAttribute> customerAttributes = customer.getAttributes();

      for (CustomerOptionSet optSet : optionSet) {

        com.wms.core.business.customer.model.attribute.CustomerOption custOption =
            optSet.getCustomerOption();
        if (!custOption.isActive()) {
          continue;
        }
        CustomerOption customerOption = options.get(custOption.getId());

        optionPopulator.setOptionSet(optSet);

        if (customerOption == null) {
          customerOption = new CustomerOption();
          customerOption.setId(custOption.getId());
          customerOption.setType(custOption.getCustomerOptionType());
          customerOption.setName(custOption.getDescriptionsSettoList().get(0).getName());
        }

        optionPopulator.populate(custOption, customerOption, store, language);
        options.put(customerOption.getId(), customerOption);

        if (!CollectionUtils.isEmpty(customerAttributes)) {
          for (CustomerAttribute customerAttribute : customerAttributes) {
            if (customerAttribute.getCustomerOption().getId().longValue()
                == customerOption.getId()) {
              CustomerOptionValue selectedValue = new CustomerOptionValue();
              com.wms.core.business.customer.model.attribute.CustomerOptionValue attributeValue =
                  customerAttribute.getCustomerOptionValue();
              selectedValue.setId(attributeValue.getId());
              CustomerOptionValueDescription optValue =
                  attributeValue.getDescriptionsSettoList().get(0);
              selectedValue.setName(optValue.getName());
              customerOption.setDefaultValue(selectedValue);
              if (customerOption.getType().equalsIgnoreCase(CustomerOptionType.Text.name())) {
                selectedValue.setName(customerAttribute.getTextValue());
              }
            }
          }
        }
      }
    }

    model.addAttribute("options", options.values());
  }
  /**
   * Deserves shop and admin
   *
   * @param request
   * @param locale
   * @return
   * @throws Exception
   */
  @PreAuthorize("hasRole('CUSTOMER')")
  @RequestMapping(
      value = {"/admin/customers/attributes/save.html"},
      method = RequestMethod.POST,
      produces = "application/json")
  public @ResponseBody String saveCustomerAttributes(HttpServletRequest request, Locale locale)
      throws Exception {

    AjaxResponse resp = new AjaxResponse();

    MerchantStore store = (MerchantStore) request.getAttribute(Constants.ADMIN_STORE);

    // 1=1&2=on&3=eeee&4=on&customer=1

    @SuppressWarnings("rawtypes")
    Enumeration parameterNames = request.getParameterNames();

    Customer customer = null;

    while (parameterNames.hasMoreElements()) {

      String parameterName = (String) parameterNames.nextElement();
      String parameterValue = request.getParameter(parameterName);
      if (CUSTOMER_ID_PARAMETER.equals(parameterName)) {
        customer = customerService.getById(new Long(parameterValue));
        break;
      }
    }

    if (customer == null) {
      LOGGER.error("Customer id [customer] is not defined in the parameters");
      resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
      return resp.toJSONString();
    }

    if (customer.getMerchantStore().getId().intValue() != store.getId().intValue()) {
      LOGGER.error("Customer id does not belong to current store");
      resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
      return resp.toJSONString();
    }

    List<CustomerAttribute> customerAttributes =
        customerAttributeService.getByCustomer(store, customer);
    Map<Long, CustomerAttribute> customerAttributesMap = new HashMap<Long, CustomerAttribute>();

    for (CustomerAttribute attr : customerAttributes) {
      customerAttributesMap.put(attr.getCustomerOption().getId(), attr);
    }

    parameterNames = request.getParameterNames();

    while (parameterNames.hasMoreElements()) {

      String parameterName = (String) parameterNames.nextElement();
      String parameterValue = request.getParameter(parameterName);
      try {

        String[] parameterKey = parameterName.split("-");
        com.wms.core.business.customer.model.attribute.CustomerOption customerOption = null;
        com.wms.core.business.customer.model.attribute.CustomerOptionValue customerOptionValue =
            null;

        if (CUSTOMER_ID_PARAMETER.equals(parameterName)) {
          continue;
        }

        if (parameterKey.length > 1) {
          // parse key - value
          String key = parameterKey[0];
          String value = parameterKey[1];
          // should be on
          customerOption = customerOptionService.getById(new Long(key));
          customerOptionValue = customerOptionValueService.getById(new Long(value));

        } else {
          customerOption = customerOptionService.getById(new Long(parameterName));
          customerOptionValue = customerOptionValueService.getById(new Long(parameterValue));
        }

        // get the attribute
        // CustomerAttribute attribute = customerAttributeService.getByCustomerOptionId(store,
        // customer.getId(), customerOption.getId());
        CustomerAttribute attribute = customerAttributesMap.get(customerOption.getId());
        if (attribute == null) {
          attribute = new CustomerAttribute();
          attribute.setCustomer(customer);
          attribute.setCustomerOption(customerOption);
        } else {
          customerAttributes.remove(attribute);
        }

        if (customerOption.getCustomerOptionType().equals(CustomerOptionType.Text.name())) {
          if (!StringUtils.isBlank(parameterValue)) {
            attribute.setCustomerOptionValue(customerOptionValue);
            attribute.setTextValue(parameterValue);
          } else {
            attribute.setTextValue(null);
          }
        } else {
          attribute.setCustomerOptionValue(customerOptionValue);
        }

        if (attribute.getId() != null && attribute.getId().longValue() > 0) {
          if (attribute.getCustomerOptionValue() == null) {
            customerAttributeService.delete(attribute);
          } else {
            customerAttributeService.update(attribute);
          }
        } else {
          customerAttributeService.save(attribute);
        }

      } catch (Exception e) {
        LOGGER.error("Cannot get parameter information " + parameterName, e);
      }
    }

    // and now the remaining to be removed
    for (CustomerAttribute attr : customerAttributes) {
      customerAttributeService.delete(attr);
    }

    resp.setStatus(AjaxResponse.RESPONSE_STATUS_SUCCESS);
    return resp.toJSONString();
  }