public async Task <ProductDetailsAttributeChangeModel> Handle(GetProductDetailsAttributeChange request, CancellationToken cancellationToken)
        {
            var model = new ProductDetailsAttributeChangeModel();

            string attributeXml = await _mediator.Send(new GetParseProductAttributes()
            {
                Product = request.Product, Form = request.Form
            });

            string warehouseId = _shoppingCartSettings.AllowToSelectWarehouse ?
                                 request.Form["WarehouseId"].ToString() :
                                 request.Product.UseMultipleWarehouses ? request.Store.DefaultWarehouseId :
                                 (string.IsNullOrEmpty(request.Store.DefaultWarehouseId) ? request.Product.WarehouseId : request.Store.DefaultWarehouseId);

            //rental attributes
            DateTime?rentalStartDate = null;
            DateTime?rentalEndDate   = null;

            if (request.Product.ProductType == ProductType.Reservation)
            {
                request.Product.ParseReservationDates(request.Form, out rentalStartDate, out rentalEndDate);
            }

            model.Sku  = request.Product.FormatSku(attributeXml, _productAttributeParser);
            model.Mpn  = request.Product.FormatMpn(attributeXml, _productAttributeParser);
            model.Gtin = request.Product.FormatGtin(attributeXml, _productAttributeParser);

            if (await _permissionService.Authorize(StandardPermissionProvider.DisplayPrices) && !request.Product.CustomerEntersPrice && request.Product.ProductType != ProductType.Auction)
            {
                //we do not calculate price of "customer enters price" option is enabled
                var unitprice = await _priceCalculationService.GetUnitPrice(request.Product,
                                                                            request.Customer,
                                                                            ShoppingCartType.ShoppingCart,
                                                                            1, attributeXml, 0,
                                                                            rentalStartDate, rentalEndDate,
                                                                            true);

                decimal discountAmount             = unitprice.discountAmount;
                List <AppliedDiscount> scDiscounts = unitprice.appliedDiscounts;
                decimal finalPrice   = unitprice.unitprice;
                var     productprice = await _taxService.GetProductPrice(request.Product, finalPrice);

                decimal finalPriceWithDiscountBase = productprice.productprice;
                decimal taxRate = productprice.taxRate;
                decimal finalPriceWithDiscount = await _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceWithDiscountBase, request.Currency);

                model.Price = _priceFormatter.FormatPrice(finalPriceWithDiscount);
            }
            //stock
            model.StockAvailability = request.Product.FormatStockMessage(warehouseId, attributeXml, _localizationService, _productAttributeParser);

            //back in stock subscription
            if ((request.Product.ManageInventoryMethod == ManageInventoryMethod.ManageStockByAttributes ||
                 request.Product.ManageInventoryMethod == ManageInventoryMethod.ManageStock) &&
                request.Product.BackorderMode == BackorderMode.NoBackorders &&
                request.Product.AllowBackInStockSubscriptions)
            {
                var combination = _productAttributeParser.FindProductAttributeCombination(request.Product, attributeXml);

                if (combination != null)
                {
                    if (request.Product.GetTotalStockQuantityForCombination(combination, warehouseId: request.Store.DefaultWarehouseId) <= 0)
                    {
                        model.DisplayBackInStockSubscription = true;
                    }
                }

                if (request.Product.ManageInventoryMethod == ManageInventoryMethod.ManageStock)
                {
                    model.DisplayBackInStockSubscription = request.Product.AllowBackInStockSubscriptions;
                    attributeXml = "";
                }

                var subscription = await _backInStockSubscriptionService
                                   .FindSubscription(request.Customer.Id,
                                                     request.Product.Id, attributeXml, request.Store.Id, warehouseId);

                if (subscription != null)
                {
                    model.ButtonTextBackInStockSubscription = _localizationService.GetResource("BackInStockSubscriptions.DeleteNotifyWhenAvailable");
                }
                else
                {
                    model.ButtonTextBackInStockSubscription = _localizationService.GetResource("BackInStockSubscriptions.NotifyMeWhenAvailable");
                }
            }


            //conditional attributes
            if (request.ValidateAttributeConditions)
            {
                var attributes = request.Product.ProductAttributeMappings;
                foreach (var attribute in attributes)
                {
                    var conditionMet = _productAttributeParser.IsConditionMet(request.Product, attribute, attributeXml);
                    if (conditionMet.HasValue)
                    {
                        if (conditionMet.Value)
                        {
                            model.EnabledAttributeMappingIds.Add(attribute.Id);
                        }
                        else
                        {
                            model.DisabledAttributeMappingids.Add(attribute.Id);
                        }
                    }
                }
            }
            //picture. used when we want to override a default product picture when some attribute is selected
            if (request.LoadPicture)
            {
                //first, try to get product attribute combination picture
                var pictureId = request.Product.ProductAttributeCombinations.Where(x => x.AttributesXml == attributeXml).FirstOrDefault()?.PictureId ?? "";
                //then, let's see whether we have attribute values with pictures
                if (string.IsNullOrEmpty(pictureId))
                {
                    pictureId = _productAttributeParser.ParseProductAttributeValues(request.Product, attributeXml)
                                .FirstOrDefault(attributeValue => !string.IsNullOrEmpty(attributeValue.PictureId))?.PictureId ?? "";
                }

                if (!string.IsNullOrEmpty(pictureId))
                {
                    var pictureModel = new PictureModel {
                        Id = pictureId,
                        FullSizeImageUrl = await _pictureService.GetPictureUrl(pictureId),
                        ImageUrl         = await _pictureService.GetPictureUrl(pictureId, _mediaSettings.ProductDetailsPictureSize)
                    };
                    model.PictureFullSizeUrl    = pictureModel.FullSizeImageUrl;
                    model.PictureDefaultSizeUrl = pictureModel.ImageUrl;
                }
            }
            return(model);
        }
        public virtual async Task <IList <string> > GetShoppingCartItemAttributeWarnings(Customer customer,
                                                                                         Product product, ShoppingCartItem shoppingCartItem, bool ignoreNonCombinableAttributes = false)
        {
            if (product == null)
            {
                throw new ArgumentNullException(nameof(product));
            }

            var warnings = new List <string>();

            //ensure it's our attributes
            var attributes1 = _productAttributeParser.ParseProductAttributeMappings(product, shoppingCartItem.Attributes).ToList();

            if (product.ProductTypeId == ProductType.BundledProduct)
            {
                foreach (var bundle in product.BundleProducts)
                {
                    var p1 = await _productService.GetProductById(bundle.ProductId);

                    if (p1 != null)
                    {
                        var a1 = _productAttributeParser.ParseProductAttributeMappings(p1, shoppingCartItem.Attributes).ToList();
                        attributes1.AddRange(a1);
                    }
                }
            }
            if (ignoreNonCombinableAttributes)
            {
                attributes1 = attributes1.Where(x => !x.IsNonCombinable()).ToList();
            }

            //foreach (var attribute in attributes1)
            //{
            //    if (string.IsNullOrEmpty(attribute.ProductId))
            //    {
            //        warnings.Add("Attribute error");
            //        return warnings;
            //    }
            //}

            //validate required product attributes (whether they're chosen/selected/entered)
            var attributes2 = product.ProductAttributeMappings.ToList();

            if (product.ProductTypeId == ProductType.BundledProduct)
            {
                foreach (var bundle in product.BundleProducts)
                {
                    var p1 = await _productService.GetProductById(bundle.ProductId);

                    if (p1 != null && p1.ProductAttributeMappings.Any())
                    {
                        attributes2.AddRange(p1.ProductAttributeMappings);
                    }
                }
            }
            if (ignoreNonCombinableAttributes)
            {
                attributes2 = attributes2.Where(x => !x.IsNonCombinable()).ToList();
            }
            //validate conditional attributes only (if specified)
            attributes2 = attributes2.Where(x =>
            {
                var conditionMet = _productAttributeParser.IsConditionMet(product, x, shoppingCartItem.Attributes);
                return(!conditionMet.HasValue || conditionMet.Value);
            }).ToList();
            foreach (var a2 in attributes2)
            {
                if (a2.IsRequired)
                {
                    bool found = false;
                    //selected product attributes
                    foreach (var a1 in attributes1)
                    {
                        if (a1.Id == a2.Id)
                        {
                            var attributeValuesStr = _productAttributeParser.ParseValues(shoppingCartItem.Attributes, a1.Id);
                            foreach (string str1 in attributeValuesStr)
                            {
                                if (!String.IsNullOrEmpty(str1.Trim()))
                                {
                                    found = true;
                                    break;
                                }
                            }
                        }
                    }

                    //if not found
                    if (!found)
                    {
                        var paa = await _productAttributeService.GetProductAttributeById(a2.ProductAttributeId);

                        if (paa != null)
                        {
                            var notFoundWarning = !string.IsNullOrEmpty(a2.TextPrompt) ?
                                                  a2.TextPrompt :
                                                  string.Format(_translationService.GetResource("ShoppingCart.SelectAttribute"), paa.GetTranslation(a => a.Name, _workContext.WorkingLanguage.Id));

                            warnings.Add(notFoundWarning);
                        }
                    }
                }

                if (a2.AttributeControlTypeId == AttributeControlType.ReadonlyCheckboxes)
                {
                    //customers cannot edit read-only attributes
                    var allowedReadOnlyValueIds = a2.ProductAttributeValues
                                                  .Where(x => x.IsPreSelected)
                                                  .Select(x => x.Id)
                                                  .ToArray();

                    var selectedReadOnlyValueIds = _productAttributeParser.ParseProductAttributeValues(product, shoppingCartItem.Attributes)
                                                   //.Where(x => x.ProductAttributeMappingId == a2.Id)
                                                   .Select(x => x.Id)
                                                   .ToArray();

                    if (!CommonHelper.ArraysEqual(allowedReadOnlyValueIds, selectedReadOnlyValueIds))
                    {
                        warnings.Add("You cannot change read-only values");
                    }
                }
            }

            //validation rules
            foreach (var pam in attributes2)
            {
                if (!pam.ValidationRulesAllowed())
                {
                    continue;
                }

                //minimum length
                if (pam.ValidationMinLength.HasValue)
                {
                    if (pam.AttributeControlTypeId == AttributeControlType.TextBox ||
                        pam.AttributeControlTypeId == AttributeControlType.MultilineTextbox)
                    {
                        var valuesStr         = _productAttributeParser.ParseValues(shoppingCartItem.Attributes, pam.Id);
                        var enteredText       = valuesStr.FirstOrDefault();
                        int enteredTextLength = String.IsNullOrEmpty(enteredText) ? 0 : enteredText.Length;

                        if (pam.ValidationMinLength.Value > enteredTextLength)
                        {
                            var _pam = await _productAttributeService.GetProductAttributeById(pam.ProductAttributeId);

                            warnings.Add(string.Format(_translationService.GetResource("ShoppingCart.TextboxMinimumLength"), _pam.GetTranslation(a => a.Name, _workContext.WorkingLanguage.Id), pam.ValidationMinLength.Value));
                        }
                    }
                }

                //maximum length
                if (pam.ValidationMaxLength.HasValue)
                {
                    if (pam.AttributeControlTypeId == AttributeControlType.TextBox ||
                        pam.AttributeControlTypeId == AttributeControlType.MultilineTextbox)
                    {
                        var valuesStr         = _productAttributeParser.ParseValues(shoppingCartItem.Attributes, pam.Id);
                        var enteredText       = valuesStr.FirstOrDefault();
                        int enteredTextLength = string.IsNullOrEmpty(enteredText) ? 0 : enteredText.Length;

                        if (pam.ValidationMaxLength.Value < enteredTextLength)
                        {
                            var _pam = await _productAttributeService.GetProductAttributeById(pam.ProductAttributeId);

                            warnings.Add(string.Format(_translationService.GetResource("ShoppingCart.TextboxMaximumLength"), _pam.GetTranslation(a => a.Name, _workContext.WorkingLanguage.Id), pam.ValidationMaxLength.Value));
                        }
                    }
                }
            }

            if (warnings.Any())
            {
                return(warnings);
            }

            //validate bundled products
            var attributeValues = _productAttributeParser.ParseProductAttributeValues(product, shoppingCartItem.Attributes);

            foreach (var attributeValue in attributeValues)
            {
                var _productAttributeMapping = product.ProductAttributeMappings.Where(x => x.ProductAttributeValues.Any(z => z.Id == attributeValue.Id)).FirstOrDefault();
                //TODO - check product.ProductAttributeMappings.Where(x => x.Id == attributeValue.ProductAttributeMappingId).FirstOrDefault();
                if (attributeValue.AttributeValueTypeId == AttributeValueType.AssociatedToProduct && _productAttributeMapping != null)
                {
                    if (ignoreNonCombinableAttributes && _productAttributeMapping.IsNonCombinable())
                    {
                        continue;
                    }

                    //associated product (bundle)
                    var associatedProduct = await _productService.GetProductById(attributeValue.AssociatedProductId);

                    if (associatedProduct != null)
                    {
                        var totalQty = shoppingCartItem.Quantity * attributeValue.Quantity;
                        var associatedProductWarnings = await GetShoppingCartItemWarnings(customer, new ShoppingCartItem()
                        {
                            ShoppingCartTypeId = shoppingCartItem.ShoppingCartTypeId,
                            StoreId            = _workContext.CurrentStore.Id,
                            Quantity           = totalQty,
                            WarehouseId        = shoppingCartItem.WarehouseId
                        }, associatedProduct, new ShoppingCartValidatorOptions());

                        foreach (var associatedProductWarning in associatedProductWarnings)
                        {
                            var productAttribute = await _productAttributeService.GetProductAttributeById(_productAttributeMapping.ProductAttributeId);

                            var attributeName      = productAttribute.GetTranslation(a => a.Name, _workContext.WorkingLanguage.Id);
                            var attributeValueName = attributeValue.GetTranslation(a => a.Name, _workContext.WorkingLanguage.Id);
                            warnings.Add(string.Format(
                                             _translationService.GetResource("ShoppingCart.AssociatedAttributeWarning"),
                                             attributeName, attributeValueName, associatedProductWarning));
                        }
                    }
                    else
                    {
                        warnings.Add(string.Format("Associated product cannot be loaded - {0}", attributeValue.AssociatedProductId));
                    }
                }
            }

            return(warnings);
        }
        public async Task <string> Handle(GetParseProductAttributes request, CancellationToken cancellationToken)
        {
            string attributesXml = "";

            #region Product attributes

            var productAttributes = request.Product.ProductAttributeMappings.ToList();
            if (request.Product.ProductType == ProductType.BundledProduct)
            {
                foreach (var bundle in request.Product.BundleProducts)
                {
                    var bp = await _productService.GetProductById(bundle.ProductId);

                    if (bp.ProductAttributeMappings.Any())
                    {
                        productAttributes.AddRange(bp.ProductAttributeMappings);
                    }
                }
            }

            foreach (var attribute in productAttributes)
            {
                string controlId = string.Format("product_attribute_{0}", attribute.Id);
                switch (attribute.AttributeControlType)
                {
                case AttributeControlType.DropdownList:
                case AttributeControlType.RadioList:
                case AttributeControlType.ColorSquares:
                case AttributeControlType.ImageSquares:
                {
                    var ctrlAttributes = request.Form[controlId];
                    if (!String.IsNullOrEmpty(ctrlAttributes))
                    {
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, ctrlAttributes);
                    }
                }
                break;

                case AttributeControlType.Checkboxes:
                {
                    var ctrlAttributes = request.Form[controlId].ToString();
                    if (!String.IsNullOrEmpty(ctrlAttributes))
                    {
                        foreach (var item in ctrlAttributes.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            if (!String.IsNullOrEmpty(item))
                            {
                                attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                            attribute, item);
                            }
                        }
                    }
                }
                break;

                case AttributeControlType.ReadonlyCheckboxes:
                {
                    //load read-only (already server-side selected) values
                    var attributeValues = attribute.ProductAttributeValues;
                    foreach (var selectedAttributeId in attributeValues
                             .Where(v => v.IsPreSelected)
                             .Select(v => v.Id)
                             .ToList())
                    {
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, selectedAttributeId);
                    }
                }
                break;

                case AttributeControlType.TextBox:
                case AttributeControlType.MultilineTextbox:
                {
                    var ctrlAttributes = request.Form[controlId].ToString();
                    if (!String.IsNullOrEmpty(ctrlAttributes))
                    {
                        string enteredText = ctrlAttributes.Trim();
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, enteredText);
                    }
                }
                break;

                case AttributeControlType.Datepicker:
                {
                    var      day          = request.Form[controlId + "_day"];
                    var      month        = request.Form[controlId + "_month"];
                    var      year         = request.Form[controlId + "_year"];
                    DateTime?selectedDate = null;
                    try
                    {
                        selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(day));
                    }
                    catch { }
                    if (selectedDate.HasValue)
                    {
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, selectedDate.Value.ToString("D"));
                    }
                }
                break;

                case AttributeControlType.FileUpload:
                {
                    Guid downloadGuid;
                    Guid.TryParse(request.Form[controlId], out downloadGuid);
                    var download = await _downloadService.GetDownloadByGuid(downloadGuid);

                    if (download != null)
                    {
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, download.DownloadGuid.ToString());
                    }
                }
                break;

                default:
                    break;
                }
            }
            //validate conditional attributes (if specified)
            foreach (var attribute in productAttributes)
            {
                var conditionMet = _productAttributeParser.IsConditionMet(request.Product, attribute, attributesXml);
                if (conditionMet.HasValue && !conditionMet.Value)
                {
                    attributesXml = _productAttributeParser.RemoveProductAttribute(attributesXml, attribute);
                }
            }

            #endregion

            #region Gift cards

            if (request.Product.IsGiftCard)
            {
                string recipientName   = "";
                string recipientEmail  = "";
                string senderName      = "";
                string senderEmail     = "";
                string giftCardMessage = "";
                foreach (string formKey in request.Form.Keys)
                {
                    if (formKey.Equals(string.Format("giftcard_{0}.RecipientName", request.Product.Id), StringComparison.OrdinalIgnoreCase))
                    {
                        recipientName = request.Form[formKey];
                        continue;
                    }
                    if (formKey.Equals(string.Format("giftcard_{0}.RecipientEmail", request.Product.Id), StringComparison.OrdinalIgnoreCase))
                    {
                        recipientEmail = request.Form[formKey];
                        continue;
                    }
                    if (formKey.Equals(string.Format("giftcard_{0}.SenderName", request.Product.Id), StringComparison.OrdinalIgnoreCase))
                    {
                        senderName = request.Form[formKey];
                        continue;
                    }
                    if (formKey.Equals(string.Format("giftcard_{0}.SenderEmail", request.Product.Id), StringComparison.OrdinalIgnoreCase))
                    {
                        senderEmail = request.Form[formKey];
                        continue;
                    }
                    if (formKey.Equals(string.Format("giftcard_{0}.Message", request.Product.Id), StringComparison.OrdinalIgnoreCase))
                    {
                        giftCardMessage = request.Form[formKey];
                        continue;
                    }
                }

                attributesXml = _productAttributeParser.AddGiftCardAttribute(attributesXml,
                                                                             recipientName, recipientEmail, senderName, senderEmail, giftCardMessage);
            }

            #endregion

            return(attributesXml);
        }
        // TODO
        // use it from ShoppingCartController
        private string ParseProductAttributes(Product product, IFormCollection form, List <string> errors)
        {
            var attributesXml = string.Empty;

            var productAttributes = _productAttributeService.GetProductAttributeMappingsByProductId(product.Id);

            foreach (var attribute in productAttributes)
            {
                var controlId = $"product_attribute_{attribute.Id}";
                switch (attribute.AttributeControlType)
                {
                case AttributeControlType.DropdownList:
                case AttributeControlType.RadioList:
                case AttributeControlType.ColorSquares:
                case AttributeControlType.ImageSquares:
                {
                    var ctrlAttributes = form[controlId];
                    if (!StringValues.IsNullOrEmpty(ctrlAttributes))
                    {
                        var selectedAttributeId = int.Parse(ctrlAttributes);
                        if (selectedAttributeId > 0)
                        {
                            //get quantity entered by customer
                            var quantity    = 1;
                            var quantityStr = form[$"product_attribute_{attribute.Id}_{selectedAttributeId}_qty"];
                            if (!StringValues.IsNullOrEmpty(quantityStr) && (!int.TryParse(quantityStr, out quantity) || quantity < 1))
                            {
                                errors.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive"));
                            }

                            attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                        attribute, selectedAttributeId.ToString(), quantity > 1 ? (int?)quantity : null);
                        }
                    }
                }
                break;

                case AttributeControlType.Checkboxes:
                {
                    var ctrlAttributes = form[controlId];
                    if (!StringValues.IsNullOrEmpty(ctrlAttributes))
                    {
                        foreach (var item in ctrlAttributes.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            var selectedAttributeId = int.Parse(item);
                            if (selectedAttributeId > 0)
                            {
                                //get quantity entered by customer
                                var quantity    = 1;
                                var quantityStr = form[$"product_attribute_{attribute.Id}_{item}_qty"];
                                if (!StringValues.IsNullOrEmpty(quantityStr) && (!int.TryParse(quantityStr, out quantity) || quantity < 1))
                                {
                                    errors.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive"));
                                }

                                attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                            attribute, selectedAttributeId.ToString(), quantity > 1 ? (int?)quantity : null);
                            }
                        }
                    }
                }
                break;

                case AttributeControlType.ReadonlyCheckboxes:
                {
                    //load read-only (already server-side selected) values
                    var attributeValues = _productAttributeService.GetProductAttributeValues(attribute.Id);
                    foreach (var selectedAttributeId in attributeValues
                             .Where(v => v.IsPreSelected)
                             .Select(v => v.Id)
                             .ToList())
                    {
                        //get quantity entered by customer
                        var quantity    = 1;
                        var quantityStr = form[$"product_attribute_{attribute.Id}_{selectedAttributeId}_qty"];
                        if (!StringValues.IsNullOrEmpty(quantityStr) && (!int.TryParse(quantityStr, out quantity) || quantity < 1))
                        {
                            errors.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive"));
                        }

                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, selectedAttributeId.ToString(), quantity > 1 ? (int?)quantity : null);
                    }
                }
                break;

                case AttributeControlType.TextBox:
                case AttributeControlType.MultilineTextbox:
                {
                    var ctrlAttributes = form[controlId];
                    if (!StringValues.IsNullOrEmpty(ctrlAttributes))
                    {
                        var enteredText = ctrlAttributes.ToString().Trim();
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, enteredText);
                    }
                }
                break;

                case AttributeControlType.Datepicker:
                {
                    var      day          = form[controlId + "_day"];
                    var      month        = form[controlId + "_month"];
                    var      year         = form[controlId + "_year"];
                    DateTime?selectedDate = null;
                    try
                    {
                        selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(day));
                    }
                    catch { }
                    if (selectedDate.HasValue)
                    {
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, selectedDate.Value.ToString("D"));
                    }
                }
                break;

                case AttributeControlType.FileUpload:
                {
                    Guid.TryParse(form[controlId], out Guid downloadGuid);
                    var download = _downloadService.GetDownloadByGuid(downloadGuid);
                    if (download != null)
                    {
                        attributesXml = _productAttributeParser.AddProductAttribute(attributesXml,
                                                                                    attribute, download.DownloadGuid.ToString());
                    }
                }
                break;

                default:
                    break;
                }
            }
            //validate conditional attributes (if specified)
            foreach (var attribute in productAttributes)
            {
                var conditionMet = _productAttributeParser.IsConditionMet(attribute, attributesXml);
                if (conditionMet.HasValue && !conditionMet.Value)
                {
                    attributesXml = _productAttributeParser.RemoveProductAttribute(attributesXml, attribute);
                }
            }

            return(attributesXml);
        }