@SuppressWarnings("unchecked")
  @RequestMapping(
      value = "/admin/options/paging.html",
      method = RequestMethod.POST,
      produces = "application/json")
  public @ResponseBody String pageOptions(
      HttpServletRequest request, HttpServletResponse response) {

    String optionName = request.getParameter("name");

    AjaxResponse resp = new AjaxResponse();

    try {

      Language language = (Language) request.getAttribute("LANGUAGE");

      MerchantStore store = (MerchantStore) request.getAttribute("MERCHANT_STORE");

      List<ProductOption> options = null;

      if (!StringUtils.isBlank(optionName)) {

        options = productOptionService.getByName(store, optionName, language);

      } else {

        options = productOptionService.listByStore(store, language);
      }

      for (ProductOption option : options) {

        @SuppressWarnings("rawtypes")
        Map entry = new HashMap();
        entry.put("optionId", option.getId());

        ProductOptionDescription description = option.getDescriptions().iterator().next();

        entry.put("name", description.getName());
        entry.put("type", option.getProductOptionType()); // TODO resolve with option type label
        resp.addDataEntry(entry);
      }

      resp.setStatus(AjaxResponse.RESPONSE_STATUS_SUCCESS);

    } catch (Exception e) {
      LOGGER.error("Error while paging options", e);
      resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
    }

    String returnString = resp.toJSONString();

    return returnString;
  }
  @RequestMapping(value = "/admin/options/save.html", method = RequestMethod.POST)
  public String saveOption(
      @Valid @ModelAttribute("option") ProductOption option,
      BindingResult result,
      Model model,
      HttpServletRequest request)
      throws Exception {

    // display menu
    setMenu(model, request);

    MerchantStore store = (MerchantStore) request.getAttribute("MERCHANT_STORE");
    ProductOption dbEntity = null;

    if (option.getId() != null && option.getId() > 0) { // edit entry

      // get from DB
      dbEntity = productOptionService.getById(store, option.getId());

      if (dbEntity == null) {
        return "redirect:/admin/options/options.html";
      }
    }

    Map<String, Language> langs = languageService.getLanguagesMap();

    List<ProductOptionDescription> descriptions = option.getDescriptionsList();

    if (descriptions != null) {

      for (ProductOptionDescription description : descriptions) {

        String code = description.getLanguage().getCode();
        Language l = langs.get(code);
        description.setLanguage(l);
        description.setProductOption(option);
      }
    }

    option.setDescriptions(new HashSet<ProductOptionDescription>(descriptions));
    option.setMerchantSore(store);

    if (result.hasErrors()) {
      return "catalogue-options-details";
    }

    productOptionService.saveOrUpdate(option);

    model.addAttribute("success", "success");
    return "catalogue-options-details";
  }
  @RequestMapping(
      value = "/admin/options/remove.html",
      method = RequestMethod.POST,
      produces = "application/json")
  public @ResponseBody String deleteOption(
      HttpServletRequest request, HttpServletResponse response, Locale locale) {
    String sid = request.getParameter("optionId");

    MerchantStore store = (MerchantStore) request.getAttribute("MERCHANT_STORE");

    AjaxResponse resp = new AjaxResponse();

    try {

      Long id = Long.parseLong(sid);

      ProductOption entity = productOptionService.getById(store, id);

      if (entity == null
          || entity.getMerchantSore().getId().intValue() != store.getId().intValue()) {

        resp.setStatusMessage(messages.getMessage("message.unauthorized", locale));
        resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);

      } else {

        productOptionService.delete(entity);
        resp.setStatus(AjaxResponse.RESPONSE_OPERATION_COMPLETED);
      }

    } catch (Exception e) {
      LOGGER.error("Error while deleting option", e);
      resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
      resp.setErrorMessage(e);
    }

    String returnString = resp.toJSONString();

    return returnString;
  }
  private String displayOption(
      Long optionId,
      HttpServletRequest request,
      HttpServletResponse response,
      Model model,
      Locale locale)
      throws Exception {

    this.setMenu(model, request);
    MerchantStore store = (MerchantStore) request.getAttribute("MERCHANT_STORE");

    List<Language> languages = store.getLanguages();

    Set<ProductOptionDescription> descriptions = new HashSet<ProductOptionDescription>();

    ProductOption option = new ProductOption();

    if (optionId != null && optionId != 0) { // edit mode

      option = productOptionService.getById(store, optionId);

      if (option == null) {
        return "redirect:/admin/options/options.html";
      }

      Set<ProductOptionDescription> optionDescriptions = option.getDescriptions();

      for (Language l : languages) {

        ProductOptionDescription optionDescription = null;

        if (optionDescriptions != null) {

          for (ProductOptionDescription description : optionDescriptions) {

            String code = description.getLanguage().getCode();
            if (code.equals(l.getCode())) {
              optionDescription = description;
            }
          }
        }

        if (optionDescription == null) {
          optionDescription = new ProductOptionDescription();
          optionDescription.setLanguage(l);
        }

        descriptions.add(optionDescription);
      }

    } else {

      for (Language l : languages) {

        ProductOptionDescription desc = new ProductOptionDescription();
        desc.setLanguage(l);
        descriptions.add(desc);
      }
    }

    option.setDescriptions(descriptions);
    model.addAttribute("option", option);
    return "catalogue-options-details";
  }