/** {@inheritDoc} */
  @Override
  public Map<String, Collection<Object>> getAssignedVariantAttributes(
      final ProductModel baseProduct) {
    validateParameterNotNullStandardMessage("baseProduct", baseProduct);

    final Map<String, Collection<Object>> result = new HashMap<String, Collection<Object>>();
    final Collection<VariantProductModel> variantModelList = baseProduct.getVariants();
    final List<VariantAttributeDescriptorModel> vadList =
        getVariantAttributesForVariantType(baseProduct.getVariantType());

    // iterate trough all variants to get the qualifier with appropriate values
    for (final VariantProductModel variant : variantModelList) {
      for (final VariantAttributeDescriptorModel item : vadList) {

        Collection values = result.get(item.getQualifier());
        if (values == null) {
          values = new LinkedHashSet();
          result.put(item.getQualifier(), values);
        }

        // there is no chance to read the attribute value in SL, because it"s not a part of the
        // model.
        //	final Object value = variant.getAttributeProvider().getAttribute(item.getQualifier());
        // Currently the jalo-solution has to be used

        values.add(getVariantAttributeValue(variant, item.getQualifier()));
      }
    }
    if (LOG.isDebugEnabled()) {
      LOG.debug(result.size() + " variant attributes with assigned values found");
    }

    return result;
  }
  /** {@inheritDoc} */
  @Override
  public Collection<VariantProductModel> getVariantProductForAttributeValues(
      final ProductModel baseProduct, final Map<String, Object> filterValues) {
    validateParameterNotNullStandardMessage("baseProduct", baseProduct);

    final Collection<VariantProductModel> result = new ArrayList<VariantProductModel>();
    final List<VariantAttributeDescriptorModel> vadList =
        getVariantAttributesForVariantType(baseProduct.getVariantType());
    final Collection<VariantProductModel> allBaseProductVariants = baseProduct.getVariants();

    if (filterValues == null || filterValues.isEmpty()) {
      // no filter defined - no results.
      if (LOG.isDebugEnabled()) {
        LOG.debug("The filter values haven't been set, no matching variants in cases like this.");
      }
      return result;
    }

    // iterate through all variants and filter those with matching qualifier and values
    for (final VariantProductModel variant : allBaseProductVariants) {
      boolean add = true;
      for (final Iterator<Map.Entry<String, Object>> iterator = filterValues.entrySet().iterator();
          iterator.hasNext(); ) {
        if (!add) {
          break; // the filter element, which has been checked doesn't match, skip checking of
                 // addtional filter elements, go to next variant.
        }
        final Map.Entry entry = iterator.next();
        final String filterKey = (String) entry.getKey();
        final Object filterValue = entry.getValue();
        //	compare the filterKey and filterValue with all attributes (qualifier-value) of the
        // variantType.
        for (final VariantAttributeDescriptorModel attrDesc : vadList) {
          final String qualifier = attrDesc.getQualifier();
          final Object variantAttributeValue = getVariantAttributeValue(variant, qualifier);

          if (!(filterKey.equals(qualifier)
              && (filterValue == variantAttributeValue
                  || (filterValue != null && filterValue.equals(variantAttributeValue))))) {
            add = false;
          } else {
            add =
                true; // the current filter key and values matches for the current variant, go to
                      // next filter-element to check it.
            break;
          }
        }
      }
      if (add) {
        result.add(variant);
      }
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(result.size() + " matching variants have been found.");
    }
    return result;
  }
 @Test
 public void testVariant() throws Exception {
   processFile(
       productId,
       "base_product-",
       new ProductContent() {
         @Override
         public void writeContent(final PrintWriter writer) throws IOException {
           writer.print("ApparelSizeVariantProduct");
           super.writeContent(writer);
         }
       });
   final Long variantId = Long.valueOf(Math.abs((long) random.nextInt()));
   final ProductModel product =
       processFile(
           productId,
           "variant-",
           new FileContent() {
             @Override
             public void writeContent(final PrintWriter writer) throws IOException {
               writer.print(variantId);
               writer.print(SEPARATOR);
               writer.print(SEPARATOR);
               writer.print("black");
               writer.print(SEPARATOR);
               writer.print("L");
             }
           });
   final ApparelSizeVariantProductModel variant =
       (ApparelSizeVariantProductModel) productService.getProductForCode(variantId.toString());
   Assert.assertEquals("ApparelSizeVariantProduct", product.getVariantType().getCode());
   Assert.assertEquals(product, variant.getBaseProduct());
   Assert.assertEquals("black", variant.getStyle(Locale.ENGLISH));
   Assert.assertNull(variant.getStyle(Locale.GERMAN));
   Assert.assertEquals("L", variant.getSize(Locale.ENGLISH));
   Assert.assertNull(variant.getSize(Locale.GERMAN));
 }