public IEnumerable<ProductOverviewModel> PrepareProductOverviewModels(
			IEnumerable<Product> products,
			bool preparePriceModel = true, 
			bool preparePictureModel = true,
			int? productThumbPictureSize = null, 
			bool prepareSpecificationAttributes = false,
			bool forceRedirectionAfterAddingToCart = false, 
			bool prepareColorAttributes = false,
			bool prepareManufacturers = false,
            bool isCompact = false,
			bool prepareFullDescription = false,
			bool isCompareList = false)
        {
            if (products == null)
                throw new ArgumentNullException("products");

            // PERF!!
            var currentStore = _services.StoreContext.CurrentStore;
            var currentCustomer = _services.WorkContext.CurrentCustomer;
            var workingCurrency = _services.WorkContext.WorkingCurrency;
            var displayPrices = _services.Permissions.Authorize(StandardPermissionProvider.DisplayPrices);
            var enableShoppingCart = _services.Permissions.Authorize(StandardPermissionProvider.EnableShoppingCart);
            var enableWishlist = _services.Permissions.Authorize(StandardPermissionProvider.EnableWishlist);
            var taxDisplayType = _services.WorkContext.GetTaxDisplayTypeFor(currentCustomer, currentStore.Id);
            var cachedManufacturerModels = new Dictionary<int, ManufacturerOverviewModel>();

            string taxInfo = T(taxDisplayType == TaxDisplayType.IncludingTax ? "Tax.InclVAT" : "Tax.ExclVAT");
            var legalInfo = "";

            var res = new Dictionary<string, LocalizedString>(StringComparer.OrdinalIgnoreCase)
            {
                { "Products.CallForPrice", T("Products.CallForPrice") },
                { "Products.PriceRangeFrom", T("Products.PriceRangeFrom") },
                { "Media.Product.ImageLinkTitleFormat", T("Media.Product.ImageLinkTitleFormat") },
                { "Media.Product.ImageAlternateTextFormat", T("Media.Product.ImageAlternateTextFormat") },
                { "Products.DimensionsValue", T("Products.DimensionsValue") },
                { "Common.AdditionalShippingSurcharge", T("Common.AdditionalShippingSurcharge") }
            };

            if (_taxSettings.ShowLegalHintsInProductList)
            {
                if (_topicService.Value.GetTopicBySystemName("ShippingInfo", currentStore.Id) == null)
                {
                    legalInfo = T("Tax.LegalInfoFooter2").Text.FormatInvariant(taxInfo);
                }
                else
                {
                    var shippingInfoLink = _urlHelper.RouteUrl("Topic", new { SystemName = "shippinginfo" });
                    legalInfo = T("Tax.LegalInfoFooter").Text.FormatInvariant(taxInfo, shippingInfoLink);
                }
            }

            var cargoData = _priceCalculationService.CreatePriceCalculationContext(products);

            var models = new List<ProductOverviewModel>();

            foreach (var product in products)
            {
                var contextProduct = product;
                var finalPrice = decimal.Zero;

                var model = new ProductOverviewModel
                {
                    Id = product.Id,
                    Name = product.GetLocalized(x => x.Name).EmptyNull(),
                    ShortDescription = product.GetLocalized(x => x.ShortDescription),
                    SeName = product.GetSeName()
                };

                if (prepareFullDescription)
                {
                    model.FullDescription = product.GetLocalized(x => x.FullDescription);
                }

                // price
                if (preparePriceModel)
                {
                    #region Prepare product price

                    var priceModel = new ProductOverviewModel.ProductPriceModel
                    {
                        ForceRedirectionAfterAddingToCart = forceRedirectionAfterAddingToCart,
                        ShowDiscountSign = _catalogSettings.ShowDiscountSign
                    };

                    if (product.ProductType == ProductType.GroupedProduct)
                    {
                        #region Grouped product

                        priceModel.DisableBuyButton = true;
                        priceModel.DisableWishListButton = true;
                        priceModel.AvailableForPreOrder = false;

                        var searchContext = new ProductSearchContext
                        {
                            OrderBy = ProductSortingEnum.Position,
                            StoreId = currentStore.Id,
                            ParentGroupedProductId = product.Id,
                            PageSize = int.MaxValue,
                            VisibleIndividuallyOnly = false
                        };

                        var associatedProducts = _productService.SearchProducts(searchContext);

                        if (associatedProducts.Count > 0)
                        {
                            contextProduct = associatedProducts.OrderBy(x => x.DisplayOrder).First();

                            if (displayPrices && _catalogSettings.PriceDisplayType != PriceDisplayType.Hide)
                            {
                                decimal? displayPrice = null;
                                bool displayFromMessage = false;

                                if (_catalogSettings.PriceDisplayType == PriceDisplayType.PreSelectedPrice)
                                {
                                    displayPrice = _priceCalculationService.GetPreselectedPrice(contextProduct, cargoData);
                                }
                                else if (_catalogSettings.PriceDisplayType == PriceDisplayType.PriceWithoutDiscountsAndAttributes)
                                {
                                    displayPrice = _priceCalculationService.GetFinalPrice(contextProduct, null, currentCustomer, decimal.Zero, false, 1, null, cargoData);
                                }
                                else
                                {
                                    displayFromMessage = true;
                                    displayPrice = _priceCalculationService.GetLowestPrice(product, cargoData, associatedProducts, out contextProduct);
                                }

                                if (contextProduct != null && !contextProduct.CustomerEntersPrice)
                                {
                                    if (contextProduct.CallForPrice)
                                    {
                                        priceModel.OldPrice = null;
                                        priceModel.Price = res["Products.CallForPrice"];
                                    }
                                    else if (displayPrice.HasValue)
                                    {
                                        //calculate prices
                                        decimal taxRate = decimal.Zero;
                                        decimal oldPriceBase = _taxService.GetProductPrice(contextProduct, contextProduct.OldPrice, out taxRate);
                                        decimal finalPriceBase = _taxService.GetProductPrice(contextProduct, displayPrice.Value, out taxRate);
                                        finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workingCurrency);

                                        priceModel.OldPrice = null;

                                        if (displayFromMessage)
                                            priceModel.Price = String.Format(res["Products.PriceRangeFrom"], _priceFormatter.FormatPrice(finalPrice));
                                        else
                                            priceModel.Price = _priceFormatter.FormatPrice(finalPrice);

                                        priceModel.HasDiscount = (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero);
                                    }
                                    else
                                    {
                                        // Actually it's not possible (we presume that displayPrice always has a value). We never should get here
                                        Debug.WriteLine(string.Format("Cannot calculate displayPrice for product #{0}", product.Id));
                                    }
                                }
                            }
                        }

                        #endregion
                    }
                    else
                    {
                        #region Simple product

                        //add to cart button
                        priceModel.DisableBuyButton = product.DisableBuyButton || !enableShoppingCart || !displayPrices;

                        //add to wishlist button
                        priceModel.DisableWishListButton = product.DisableWishlistButton || !enableWishlist || !displayPrices;

                        //pre-order
                        priceModel.AvailableForPreOrder = product.AvailableForPreOrder;

                        //prices
                        if (displayPrices && _catalogSettings.PriceDisplayType != PriceDisplayType.Hide && !product.CustomerEntersPrice)
                        {
                            if (product.CallForPrice)
                            {
                                //call for price
                                priceModel.OldPrice = null;
                                priceModel.Price = res["Products.CallForPrice"];
                            }
                            else
                            {
                                //calculate prices
                                bool displayFromMessage = false;
                                decimal displayPrice = decimal.Zero;

                                if (_catalogSettings.PriceDisplayType == PriceDisplayType.PreSelectedPrice)
                                {
                                    displayPrice = _priceCalculationService.GetPreselectedPrice(product, cargoData);
                                }
                                else if (_catalogSettings.PriceDisplayType == PriceDisplayType.PriceWithoutDiscountsAndAttributes)
                                {
                                    displayPrice = _priceCalculationService.GetFinalPrice(product, null, currentCustomer, decimal.Zero, false, 1, null, cargoData);
                                }
                                else
                                {
                                    displayPrice = _priceCalculationService.GetLowestPrice(product, cargoData, out displayFromMessage);
                                }

                                decimal taxRate = decimal.Zero;
                                decimal oldPriceBase = _taxService.GetProductPrice(product, product.OldPrice, out taxRate);
                                decimal finalPriceBase = _taxService.GetProductPrice(product, displayPrice, out taxRate);

                                decimal oldPrice = _currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, workingCurrency);
                                finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workingCurrency);

                                priceModel.HasDiscount = (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero);

                                if (displayFromMessage)
                                {
                                    priceModel.OldPrice = null;
                                    priceModel.Price = String.Format(res["Products.PriceRangeFrom"], _priceFormatter.FormatPrice(finalPrice));
                                }
                                else
                                {
                                    if (priceModel.HasDiscount)
                                    {
                                        priceModel.OldPrice = _priceFormatter.FormatPrice(oldPrice);
                                        priceModel.Price = _priceFormatter.FormatPrice(finalPrice);
                                    }
                                    else
                                    {
                                        priceModel.OldPrice = null;
                                        priceModel.Price = _priceFormatter.FormatPrice(finalPrice);
                                    }
                                }
                            }
                        }

                        #endregion
                    }

                    model.ProductPrice = priceModel;
                    model.ProductPrice.CallForPrice = product.CallForPrice;

                    #endregion
                }

                // color squares
                if (prepareColorAttributes && _catalogSettings.ShowColorSquaresInLists)
                {
                    #region Prepare color attributes

                    var attributes = cargoData.Attributes.Load(contextProduct.Id);
                    var colorAttribute = attributes.FirstOrDefault(x => x.AttributeControlType == AttributeControlType.ColorSquares);

                    if (colorAttribute != null)
                    {
                        var colorValues =
                            from a in colorAttribute.ProductVariantAttributeValues.Take(50)
                            where (a.ColorSquaresRgb.HasValue() && !a.ColorSquaresRgb.IsCaseInsensitiveEqual("transparent"))
                            select new ProductOverviewModel.ColorAttributeModel
                            {
                                Color = a.ColorSquaresRgb,
                                Alias = a.Alias,
                                FriendlyName = a.GetLocalized(l => l.Name)
                            };

                        if (colorValues.Any())
                        {
                            model.ColorAttributes.AddRange(colorValues.Distinct());
                        }
                    }

                    #endregion
                }

                // picture
                if (preparePictureModel)
                {
                    #region Prepare product picture

                    //If a size has been set in the view, we use it in priority
                    int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : _mediaSettings.ProductThumbPictureSize;

                    //prepare picture model
                    var defaultProductPictureCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_DEFAULTPICTURE_MODEL_KEY, product.Id, pictureSize, true,
                        _services.WorkContext.WorkingLanguage.Id, _services.WebHelper.IsCurrentConnectionSecured(), currentStore.Id);

                    model.DefaultPictureModel = _services.Cache.Get(defaultProductPictureCacheKey, () =>
                    {
                        var picture = product.GetDefaultProductPicture(_pictureService);
                        var pictureModel = new PictureModel
                        {
                            ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize, !_catalogSettings.HideProductDefaultPictures),
                            FullSizeImageUrl = _pictureService.GetPictureUrl(picture, 0, !_catalogSettings.HideProductDefaultPictures),
                            Title = string.Format(res["Media.Product.ImageLinkTitleFormat"], model.Name),
                            AlternateText = string.Format(res["Media.Product.ImageAlternateTextFormat"], model.Name)
                        };
                        return pictureModel;
                    });

                    #endregion
                }

                // specs
                if (prepareSpecificationAttributes)
                {
                    model.SpecificationAttributeModels = PrepareProductSpecificationModel(product);
                }

                model.MinPriceProductId = contextProduct.Id;
                model.ShowSku = _catalogSettings.ShowProductSku;
                model.ShowWeight = _catalogSettings.ShowWeight;
                model.ShowDimensions = _catalogSettings.ShowDimensions;
                model.Sku = contextProduct.Sku;
                model.Dimensions = res["Products.DimensionsValue"].Text.FormatCurrent(
                    contextProduct.Width.ToString("F2"),
                    contextProduct.Height.ToString("F2"),
                    contextProduct.Length.ToString("F2")
                );
                model.DimensionMeasureUnit = _measureService.GetMeasureDimensionById(_measureSettings.BaseDimensionId).Name;
                model.ThumbDimension = _mediaSettings.ProductThumbPictureSize;
                model.ShowLegalInfo = _taxSettings.ShowLegalHintsInProductList;
                model.LegalInfo = legalInfo;
                model.RatingSum = product.ApprovedRatingSum;
                model.TotalReviews = product.ApprovedTotalReviews;
                model.ShowReviews = _catalogSettings.ShowProductReviewsInProductLists;
                model.ShowDeliveryTimes = _catalogSettings.ShowDeliveryTimesInProductLists;
                model.InvisibleDeliveryTime = (product.ProductType == ProductType.GroupedProduct);

                model.IsShipEnabled = contextProduct.IsShipEnabled;
                model.DisplayDeliveryTimeAccordingToStock = contextProduct.DisplayDeliveryTimeAccordingToStock(_catalogSettings);
                model.StockAvailablity = contextProduct.FormatStockMessage(_localizationService);

                model.DisplayBasePrice = _catalogSettings.ShowBasePriceInProductLists;
                model.CompareEnabled = _catalogSettings.CompareProductsEnabled;
                model.HideBuyButtonInLists = _catalogSettings.HideBuyButtonInLists;

                if (model.ShowDeliveryTimes)
                {
                    var deliveryTime = _deliveryTimeService.GetDeliveryTime(contextProduct);
                    if (deliveryTime != null)
                    {
                        model.DeliveryTimeName = deliveryTime.GetLocalized(x => x.Name);
                        model.DeliveryTimeHexValue = deliveryTime.ColorHexValue;
                    }
                }

                if (prepareManufacturers)
                {
                    model.Manufacturers = PrepareManufacturersOverviewModel(_manufacturerService.GetProductManufacturersByProductId(product.Id), cachedManufacturerModels, false);
                }

                if (finalPrice != decimal.Zero && (_catalogSettings.ShowBasePriceInProductLists || isCompareList))
                {
                    model.BasePriceInfo = contextProduct.GetBasePriceInfo(finalPrice, _localizationService,	_priceFormatter, workingCurrency);
                }

                if (displayPrices)
                {
                    var addShippingPrice = _currencyService.ConvertCurrency(contextProduct.AdditionalShippingCharge, currentStore.PrimaryStoreCurrency, workingCurrency);

                    if (addShippingPrice > 0)
                    {
                        model.TransportSurcharge = res["Common.AdditionalShippingSurcharge"].Text.FormatCurrent(_priceFormatter.FormatPrice(addShippingPrice, true, false));
                    }
                }

                if (contextProduct.Weight > 0)
                {
                    model.Weight = "{0} {1}".FormatCurrent(contextProduct.Weight.ToString("F2"), _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).Name);
                }

                // IsNew
                if (_catalogSettings.LabelAsNewForMaxDays.HasValue)
                {
                    model.IsNew = ((DateTime.UtcNow - product.CreatedOnUtc).Days <= _catalogSettings.LabelAsNewForMaxDays.Value);
                }

                models.Add(model);
            }

            return models;
        }
        public IEnumerable<ProductOverviewModel> PrepareProductOverviewModels(IEnumerable<Product> products,
			bool preparePriceModel = true, bool preparePictureModel = true,
			int? productThumbPictureSize = null, bool prepareSpecificationAttributes = false,
			bool forceRedirectionAfterAddingToCart = false, bool prepareColorAttributes = false)
        {
            if (products == null)
                throw new ArgumentNullException("products");

            var models = new List<ProductOverviewModel>();

            foreach (var product in products)
            {
                var minPriceProduct = product;

                var model = new ProductOverviewModel()
                {
                    Id = product.Id,
                    Name = product.GetLocalized(x => x.Name).EmptyNull(),
                    ShortDescription = product.GetLocalized(x => x.ShortDescription),
                    FullDescription = product.GetLocalized(x => x.FullDescription),
                    SeName = product.GetSeName()
                };

                // price
                if (preparePriceModel)
                {
                    #region Prepare product price

                    var priceModel = new ProductOverviewModel.ProductPriceModel()
                    {
                        ForceRedirectionAfterAddingToCart = forceRedirectionAfterAddingToCart,
                        ShowDiscountSign = _catalogSettings.ShowDiscountSign
                    };

                    switch (product.ProductType)
                    {
                        case ProductType.GroupedProduct:
                            {
                                #region Grouped product

                                var searchContext = new ProductSearchContext()
                                {
                                    StoreId = _services.StoreContext.CurrentStore.Id,
                                    ParentGroupedProductId = product.Id,
                                    PageSize = int.MaxValue,
                                    VisibleIndividuallyOnly = false
                                };

                                var associatedProducts = _productService.SearchProducts(searchContext);

                                if (associatedProducts.Count <= 0)
                                {
                                    priceModel.OldPrice = null;
                                    priceModel.Price = null;
                                    priceModel.DisableBuyButton = true;
                                    priceModel.DisableWishListButton = true;
                                    priceModel.AvailableForPreOrder = false;
                                }
                                else
                                {
                                    priceModel.DisableBuyButton = true;
                                    priceModel.DisableWishListButton = true;
                                    priceModel.AvailableForPreOrder = false;

                                    if (_services.Permissions.Authorize(StandardPermissionProvider.DisplayPrices))
                                    {
                                        decimal? minPossiblePrice = _priceCalculationService.GetLowestPrice(product, associatedProducts, out minPriceProduct);

                                        if (minPriceProduct != null && !minPriceProduct.CustomerEntersPrice)
                                        {
                                            if (minPriceProduct.CallForPrice)
                                            {
                                                priceModel.OldPrice = null;
                                                priceModel.Price = T("Products.CallForPrice");
                                            }
                                            else if (minPossiblePrice.HasValue)
                                            {
                                                //calculate prices
                                                decimal taxRate = decimal.Zero;
                                                decimal oldPriceBase = _taxService.GetProductPrice(minPriceProduct, minPriceProduct.OldPrice, out taxRate);
                                                decimal finalPriceBase = _taxService.GetProductPrice(minPriceProduct, minPossiblePrice.Value, out taxRate);
                                                decimal finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, _services.WorkContext.WorkingCurrency);

                                                priceModel.OldPrice = null;
                                                priceModel.Price = String.Format(T("Products.PriceRangeFrom"), _priceFormatter.FormatPrice(finalPrice));
                                                priceModel.HasDiscount = finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero;
                                            }
                                            else
                                            {
                                                //Actually it's not possible (we presume that minimalPrice always has a value)
                                                //We never should get here
                                                Debug.WriteLine(string.Format("Cannot calculate minPrice for product #{0}", product.Id));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //hide prices
                                        priceModel.OldPrice = null;
                                        priceModel.Price = null;
                                    }
                                }

                                #endregion
                            }
                            break;
                        case ProductType.SimpleProduct:
                        default:
                            {
                                #region Simple product

                                //add to cart button
                                priceModel.DisableBuyButton = product.DisableBuyButton ||
                                    !_services.Permissions.Authorize(StandardPermissionProvider.EnableShoppingCart) ||
                                    !_services.Permissions.Authorize(StandardPermissionProvider.DisplayPrices);

                                //add to wishlist button
                                priceModel.DisableWishListButton = product.DisableWishlistButton ||
                                    !_services.Permissions.Authorize(StandardPermissionProvider.EnableWishlist) ||
                                    !_services.Permissions.Authorize(StandardPermissionProvider.DisplayPrices);

                                //pre-order
                                priceModel.AvailableForPreOrder = product.AvailableForPreOrder;

                                //prices
                                if (_services.Permissions.Authorize(StandardPermissionProvider.DisplayPrices))
                                {
                                    if (!product.CustomerEntersPrice)
                                    {
                                        if (product.CallForPrice)
                                        {
                                            //call for price
                                            priceModel.OldPrice = null;
                                            priceModel.Price = T("Products.CallForPrice");
                                        }
                                        else
                                        {
                                            //calculate prices
                                            bool isBundlePerItemPricing = (product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing);

                                            bool displayFromMessage = false;
                                            decimal minPossiblePrice = _priceCalculationService.GetLowestPrice(product, out displayFromMessage);

                                            decimal taxRate = decimal.Zero;
                                            decimal oldPriceBase = _taxService.GetProductPrice(product, product.OldPrice, out taxRate);
                                            decimal finalPriceBase = _taxService.GetProductPrice(product, minPossiblePrice, out taxRate);

                                            decimal oldPrice = _currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, _services.WorkContext.WorkingCurrency);
                                            decimal finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, _services.WorkContext.WorkingCurrency);

                                            priceModel.HasDiscount = (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero);

                                            // check tier prices
                                            if (product.HasTierPrices && !isBundlePerItemPricing && !displayFromMessage)
                                            {
                                                var tierPrices = new List<TierPrice>();

                                                tierPrices.AddRange(product.TierPrices
                                                    .OrderBy(tp => tp.Quantity)
                                                    .FilterByStore(_services.StoreContext.CurrentStore.Id)
                                                    .FilterForCustomer(_services.WorkContext.CurrentCustomer)
                                                    .ToList()
                                                    .RemoveDuplicatedQuantities());

                                                // When there is just one tier (with  qty 1), there are no actual savings in the list.
                                                displayFromMessage = (tierPrices.Count > 0 && !(tierPrices.Count == 1 && tierPrices[0].Quantity <= 1));
                                            }

                                            if (displayFromMessage)
                                            {
                                                priceModel.OldPrice = null;
                                                priceModel.Price = String.Format(T("Products.PriceRangeFrom"), _priceFormatter.FormatPrice(finalPrice));
                                            }
                                            else
                                            {
                                                if (priceModel.HasDiscount)
                                                {
                                                    priceModel.OldPrice = _priceFormatter.FormatPrice(oldPrice);
                                                    priceModel.Price = _priceFormatter.FormatPrice(finalPrice);
                                                }
                                                else
                                                {
                                                    priceModel.OldPrice = null;
                                                    priceModel.Price = _priceFormatter.FormatPrice(finalPrice);
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    //hide prices
                                    priceModel.OldPrice = null;
                                    priceModel.Price = null;
                                }

                                #endregion
                            }
                            break;
                    }

                    model.ProductPrice = priceModel;
                    model.ProductPrice.CallForPrice = product.CallForPrice;

                    #endregion
                }

                // picture
                if (preparePictureModel)
                {
                    #region Prepare product picture

                    //If a size has been set in the view, we use it in priority
                    int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : _mediaSettings.ProductThumbPictureSize;

                    //prepare picture model
                    var defaultProductPictureCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_DEFAULTPICTURE_MODEL_KEY, product.Id, pictureSize, true,
                        _services.WorkContext.WorkingLanguage.Id, _services.WebHelper.IsCurrentConnectionSecured(), _services.StoreContext.CurrentStore.Id);

                    model.DefaultPictureModel = _services.Cache.Get(defaultProductPictureCacheKey, () =>
                    {
                        var picture = product.GetDefaultProductPicture(_pictureService);
                        var pictureModel = new PictureModel
                        {
                            ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize),
                            FullSizeImageUrl = _pictureService.GetPictureUrl(picture),
                            Title = string.Format(T("Media.Product.ImageLinkTitleFormat"), model.Name),
                            AlternateText = string.Format(T("Media.Product.ImageAlternateTextFormat"), model.Name)
                        };
                        return pictureModel;
                    });

                    #endregion
                }

                // specs
                if (prepareSpecificationAttributes)
                {
                    model.SpecificationAttributeModels = PrepareProductSpecificationModel(product);
                }

                // available colors
                if (prepareColorAttributes && _catalogSettings.ShowColorSquaresInLists)
                {
                    #region Prepare color attributes

                    // get the FIRST color type attribute
                    var colorAttr = _productAttributeService.GetProductVariantAttributesByProductId(minPriceProduct.Id)
                        .FirstOrDefault(x => x.AttributeControlType == AttributeControlType.ColorSquares);

                    if (colorAttr != null)
                    {
                        var colorValues =
                            from a in colorAttr.ProductVariantAttributeValues.Take(50)
                            where (a.ColorSquaresRgb.HasValue() && !a.ColorSquaresRgb.IsCaseInsensitiveEqual("transparent"))
                            select new ProductOverviewModel.ColorAttributeModel()
                            {
                                Color = a.ColorSquaresRgb,
                                Alias = a.Alias,
                                FriendlyName = a.GetLocalized(l => l.Name)
                            };

                        if (colorValues.Any())
                        {
                            model.ColorAttributes.AddRange(colorValues.Distinct());
                        }
                    }

                    #endregion
                }

                var currentCustomer = _services.WorkContext.CurrentCustomer;
                var taxDisplayType = _services.WorkContext.GetTaxDisplayTypeFor(currentCustomer, _services.StoreContext.CurrentStore.Id);
                string taxInfo = T(taxDisplayType == TaxDisplayType.IncludingTax ? "Tax.InclVAT" : "Tax.ExclVAT");
                string shippingInfoLink = _urlHelper.RouteUrl("Topic", new { SystemName = "shippinginfo" });

                model.ProductMinPriceId = minPriceProduct.Id;
                model.Manufacturers = PrepareManufacturersOverviewModel(_manufacturerService.GetProductManufacturersByProductId(product.Id));
                model.ShowSku = _catalogSettings.ShowProductSku;
                model.ShowWeight = _catalogSettings.ShowWeight;
                model.ShowDimensions = _catalogSettings.ShowDimensions;
                model.Sku = minPriceProduct.Sku;
                model.Dimensions = T("Products.DimensionsValue").Text.FormatCurrent(
                    minPriceProduct.Width.ToString("F2"),
                    minPriceProduct.Height.ToString("F2"),
                    minPriceProduct.Length.ToString("F2")
                );
                model.DimensionMeasureUnit = _measureService.GetMeasureDimensionById(_measureSettings.BaseDimensionId).Name;
                model.ThumbDimension = _mediaSettings.ProductThumbPictureSize;
                model.ShowLegalInfo = _taxSettings.ShowLegalHintsInProductList;
                model.LegalInfo = T("Tax.LegalInfoFooter").Text.FormatWith(taxInfo, shippingInfoLink);
                model.RatingSum = product.ApprovedRatingSum;
                model.TotalReviews = product.ApprovedTotalReviews;
                model.ShowReviews = _catalogSettings.ShowProductReviewsInProductLists;
                model.ShowDeliveryTimes = _catalogSettings.ShowDeliveryTimesInProductLists;

                var deliveryTime = _deliveryTimeService.GetDeliveryTime(minPriceProduct);
                if (deliveryTime != null)
                {
                    model.DeliveryTimeName = deliveryTime.GetLocalized(x => x.Name);
                    model.DeliveryTimeHexValue = deliveryTime.ColorHexValue;
                }

                model.IsShipEnabled = minPriceProduct.IsShipEnabled;
                model.DisplayDeliveryTimeAccordingToStock = minPriceProduct.DisplayDeliveryTimeAccordingToStock(_catalogSettings);
                model.StockAvailablity = minPriceProduct.FormatStockMessage(_localizationService);

                model.DisplayBasePrice = _catalogSettings.ShowBasePriceInProductLists;
                model.BasePriceInfo = minPriceProduct.GetBasePriceInfo(_localizationService, _priceFormatter);
                model.CompareEnabled = _catalogSettings.CompareProductsEnabled;
                model.HideBuyButtonInLists = _catalogSettings.HideBuyButtonInLists;

                var addShippingPrice = _currencyService.ConvertCurrency(minPriceProduct.AdditionalShippingCharge,
                    _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId), _services.WorkContext.WorkingCurrency);

                if (addShippingPrice > 0)
                {
                    model.TransportSurcharge = T("Common.AdditionalShippingSurcharge").Text.FormatWith(_priceFormatter.FormatPrice(addShippingPrice, true, false));
                }

                if (minPriceProduct.Weight > 0)
                {
                    model.Weight = "{0} {1}".FormatCurrent(minPriceProduct.Weight.ToString("F2"), _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).Name);
                }

                // IsNew
                if (_catalogSettings.LabelAsNewForMaxDays.HasValue)
                {
                    model.IsNew = (DateTime.UtcNow - product.CreatedOnUtc).Days <= _catalogSettings.LabelAsNewForMaxDays.Value;
                }

                models.Add(model);
            }
            return models;
        }