@Override
  public Set<Product> getProductsBypriceFilter(Map<String, List<String>> filterParams) {
    Set<Product> productsByLowPrice = new HashSet<Product>();
    Set<Product> productsByHighPrice = new HashSet<Product>();

    Set<String> price = filterParams.keySet();

    if (price.contains("low")) {
      for (String priceLow : filterParams.get("low")) {
        for (Product product : listOfProducts) {
          if (product.getUnitPrice().compareTo(new BigDecimal(Double.parseDouble(priceLow))) > 0) {
            productsByLowPrice.add(product);
          }
        }
      }
    }
    if (price.contains("high")) {
      for (String priceLow : filterParams.get("high")) {
        for (Product product : listOfProducts) {
          if (product.getUnitPrice().compareTo(new BigDecimal(Double.parseDouble(priceLow))) < 0) {
            productsByHighPrice.add(product);
          }
        }
      }
    }
    productsByHighPrice.retainAll(productsByLowPrice);
    return productsByHighPrice;
  }
  @Override
  public Set<Product> getProductsByFilter(Map<String, List<String>> filterParams) {
    Set<Product> productsByBrand = new HashSet<Product>();
    Set<Product> productsByCategory = new HashSet<Product>();

    Set<String> criterias = filterParams.keySet();

    if (criterias.contains("brand")) {
      for (String brandName : filterParams.get("brand")) {
        for (Product product : listOfProducts) {
          if (brandName.equalsIgnoreCase(product.getManufacturer())) {
            productsByBrand.add(product);
          }
        }
      }
    }
    if (criterias.contains("category")) {
      for (String category : filterParams.get("category")) {
        productsByCategory.addAll(this.getProductsByCategory(category));
      }
    }
    if (productsByCategory.size() == 0) {
      return productsByBrand;
    }

    productsByCategory.retainAll(productsByBrand);
    return productsByCategory;
  }
  public Set<Product> getProductsByFilter(Map<String, List<String>> filterParams) {
    // TODO Auto-generated method stub
    Set<Product> productsByBrand = new HashSet<Product>();
    Set<Product> productsByCategory = new HashSet<Product>();
    Set<String> criterias = filterParams.keySet();
    if (criterias.contains("brand")) {
      for (String brandName : filterParams.get("brand")) {
        for (Product product : listOfProducts) {
          if (brandName.equalsIgnoreCase(product.getManufacturer())) {
            productsByBrand.add(product);
          }
        }
      }
    }

    if (criterias.contains("category")) {
      for (String category : filterParams.get("category")) {
        productsByCategory.addAll(this.getProductsByCategory(category));
      }
    }

    // if (criterias.contains("low")) {
    // for (String category : filterParams.get("category")) {
    // productsByCategory.addAll(this.getProductsByCategory(category));
    // }
    // }

    productsByCategory.retainAll(productsByBrand);

    return productsByCategory;
  }
  public void processOrder(String productId, long quantity) {
    Product productById = productRepository.getProductById(productId);

    if (productById.getUnitsInStock() < quantity) {
      throw new IllegalArgumentException(
          "Out of stock. Available units in stock" + productById.getUnitsInStock());
    }

    productById.setUnitsInStock(productById.getUnitsInStock() - quantity);
  }
 @Override
 public List<Product> getProductsByCategory(String category) {
   List<Product> productsByCategory = new ArrayList<Product>();
   for (Product product : listOfProducts) {
     if (category.equalsIgnoreCase(product.getCategory())) {
       productsByCategory.add(product);
     }
   }
   return productsByCategory;
 }
 @Override
 public List<Product> getProductsByManufacturer(String manufacturer) {
   List<Product> productsByManufacturer = new ArrayList<Product>();
   for (Product product : listOfProducts) {
     if (manufacturer.equalsIgnoreCase(product.getManufacturer())) {
       productsByManufacturer.add(product);
     }
   }
   return productsByManufacturer;
 }
  public List<Product> getProductsByManufacturer(String manufacturer) {
    // TODO Auto-generated method stub
    List<Product> productsByManufacturer = new ArrayList<Product>();
    for (Product product : listOfProducts) {
      if (manufacturer.equalsIgnoreCase(product.getManufacturer())) {
        productsByManufacturer.add(product);
      }
    }

    return productsByManufacturer;
  }
 public Product getProductById(String productId) {
   // TODO Auto-generated method stub
   Product productById = null;
   for (Product product : listOfProducts) {
     if (product != null
         && product.getProductId() != null
         && product.getProductId().equals(productId)) {
       productById = product;
       break;
     }
   }
   if (productById == null) {
     throw new ProductNotFoundException("No products found with the product id: " + productId);
   }
   return productById;
 }
  @Override
  public Product getProductById(String productID) {
    Product productById = null;
    for (Product product : listOfProducts) {
      if (product != null
          && product.getProductId() != null
          && product.getProductId().equals(productID)) {
        productById = product;
        break;
      }
    }

    if (productById == null) {
      throw new ProductNotFoundException("No products found withthe product id: " + productID);
    }
    return productById;
  }
  public Product getProductById(String productId) {
    Product productById = null;

    for (Product product : listOfProducts) {
      if (product != null
          && product.getProductId() != null
          && product.getProductId().equals(productId)) {
        productById = product;
        break;
      }
    }

    if (productById == null) {
      throw new IllegalArgumentException("No products found with the product id: " + productId);
    }

    return productById;
  }
  /**
   * Example URL: http://localhost:8080/webstore/products/add
   *
   * <p>Called when a POST is requested
   *
   * @param newProduct
   * @return
   */
  @RequestMapping(value = "/add", method = RequestMethod.POST)
  public String processAddNewProductForm(
      @ModelAttribute("newProduct") @Valid Product newProduct,
      BindingResult result,
      HttpServletRequest request) {
    if (result.hasErrors()) {
      return "addProduct";
    }

    String[] suppressedFields = result.getSuppressedFields();
    if (suppressedFields.length > 0) {
      throw new RuntimeException(
          "Attempting to bind disallowed fields: "
              + StringUtils.arrayToCommaDelimitedString(suppressedFields));
    }

    MultipartFile productImage = newProduct.getProductImage();
    MultipartFile productManual = newProduct.getProductManual();

    String rootDirectory = request.getSession().getServletContext().getRealPath("/");

    if (productImage != null && !productImage.isEmpty()) {
      try {
        productImage.transferTo(
            new File(rootDirectory + "resources\\images\\" + newProduct.getProductId() + ".jpg"));
      } catch (Exception e) {
        throw new RuntimeException("Product Image saving failed", e);
      }
    }

    if (productManual != null && !productManual.isEmpty()) {
      try {
        productManual.transferTo(
            new File(rootDirectory + "resources\\pdf\\" + newProduct.getProductId() + ".pdf"));
      } catch (Exception e) {
        throw new RuntimeException("Product Manual saving failed", e);
      }
    }

    productService.addProduct(newProduct);
    return "redirect:/products";
  }
  public Set<Product> getProductsByPriceFilter(Map<String, List<String>> filterParams) {

    Set<Product> productsByPriceFilter = new HashSet<Product>();
    Set<String> criterias = filterParams.keySet();
    if (criterias.contains("low")) {
      if (criterias.contains("high")) {
        String min = filterParams.get("low").get(0);
        BigDecimal minMoney = new BigDecimal(min.replaceAll(",", ""));

        String max = filterParams.get("high").get(0);
        BigDecimal maxMoney = new BigDecimal(max.replaceAll(",", ""));

        for (Product product : listOfProducts) {
          if (product.getUnitPrice().compareTo(minMoney) >= 0
              && product.getUnitPrice().compareTo(maxMoney) <= 0) {
            productsByPriceFilter.add(product);
          }
        }
      }
    }

    return productsByPriceFilter;
  }
  public InMemoryProductRepository() {
    Product iphone = new Product("P1234", "iPhone 5s", new BigDecimal(500));
    iphone.setDescription(
        "Apple iPhone 5s smartphone with 4.00-inch 640x1136 display and 8-megapixel rear camera");
    iphone.setCategory("Smart Phone");
    iphone.setManufacturer("Apple");
    iphone.setUnitsInStock(1000);

    Product laptop_dell = new Product("P1235", "Dell Inspiron", new BigDecimal(700));
    laptop_dell.setDescription(
        "Dell Inspiron 14-inch Laptop (Black) with 3rd Generation Intel Core processors");
    laptop_dell.setCategory("Laptop");
    laptop_dell.setManufacturer("Dell");
    laptop_dell.setUnitsInStock(1000);

    Product tablet_Nexus = new Product("P1236", "Nexus 7", new BigDecimal(300));
    tablet_Nexus.setDescription(
        "Google Nexus 7 is the lightest 7 inch tablet With a quad-core Qualcomm Snapdragon™ S4 Pro processor");
    tablet_Nexus.setCategory("Tablet");
    tablet_Nexus.setManufacturer("Google");
    tablet_Nexus.setUnitsInStock(1000);

    listOfProducts.add(iphone);
    listOfProducts.add(laptop_dell);
    listOfProducts.add(tablet_Nexus);
  }