/// <summary>
        /// Save a user car model configuration.
        /// </summary>
        /// <param name="summary"></param>
        /// <returns></returns>
        private CarConfigUserConfiguration SaveConfiguration(CarConfiguratorSummary summary)
        {
            var carModelProduct = _productRepository.GetByEAN(summary.SelectedModelEAN);

            if (carModelProduct == null || carModelProduct.IsOptionProduct)
            {
                throw new Exception("Unknown car model.");
            }

            var configurationProducts = summary.SelectedOptionProducts.Select(keyValuePair =>
            {
                var optionId        = keyValuePair.Key;
                var selectedProduct = keyValuePair.Value;

                var product = _productRepository.GetByEAN(selectedProduct.EAN);
                return(new CarConfigUserConfigurationProduct(carModelProduct.Id, optionId, product.Id));
            }).ToList();

            CarConfigUserConfiguration userConfiguration;

            if (summary.Code != null)
            {
                userConfiguration          = _carConfigUserConfigurationRepository.Get(summary.Code);
                userConfiguration.Products = configurationProducts;

                userConfiguration = _carConfigUserConfigurationRepository.Update(userConfiguration);

                return(userConfiguration);
            }

            var code = Guid.NewGuid().ToString("N");

            userConfiguration = new CarConfigUserConfiguration(
                carModelProduct.EAN,
                configurationProducts
                );

            userConfiguration = _carConfigUserConfigurationRepository.Add(userConfiguration, code);

            return(userConfiguration);
        }
        /// <summary>
        /// Returns the summary of the current configuration for a list of selected option products.
        /// </summary>
        /// <param name="carModelEAN"></param>
        /// <param name="selectedOptionProducts"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public CarConfiguratorSummary GetSummaryForSelectedOptionProducts(string carModelEAN,
                                                                          Dictionary <int, CarModelOptionProduct> selectedOptionProducts, string code = null)
        {
            if (carModelEAN == null)
            {
                throw new Exception("Car model EAN is missing.");
            }

            if (selectedOptionProducts == null || selectedOptionProducts.Count == 0)
            {
                throw new Exception("Selected car model option products missing.");
            }

            var carModelProduct = _productRepository.GetByEAN(carModelEAN);

            if (carModelProduct == null)
            {
                throw new Exception("Unknown car model.");
            }

            decimal basePrice    = PriceHelper.GetGrossPrice(carModelProduct.NetPrice, carModelProduct.VATRate);
            decimal optionsPrice = 0;

            var validatedSelectedOptionProducts = new Dictionary <int, CarModelOptionProduct>();

            var modelAvailableOptions = _productOptionRepository.GetProductOptionsByEAN(carModelEAN);

            foreach (var availableOption in modelAvailableOptions)
            {
                var selectedEAN = selectedOptionProducts[availableOption.Id] != null
                    ? selectedOptionProducts[availableOption.Id].EAN
                    : _productRepository.GetProductsByIds(availableOption.DefaultProductIds).Select(x => x.EAN)
                                  .FirstOrDefault();

                var userSelectedProduct = _productRepository.GetByEAN(selectedEAN);
                if (userSelectedProduct == null)
                {
                    throw new Exception("Unknown product with EAN " + selectedEAN + ".");
                }

                var availableProductsForOptions =
                    GetCarModelsOptionProducts(carModelProduct.Id, availableOption.Id);
                // _productRepository.GetOptionProducts(carModelProduct.Id, availableOption.Id);


                var userSelectedOptionProduct =
                    availableProductsForOptions.FirstOrDefault(prod => prod.EAN == selectedEAN);

                // If the product is not an product of the group for the car model
                if (userSelectedOptionProduct == null)
                {
                    continue;
                }


                validatedSelectedOptionProducts.Add(availableOption.Id, userSelectedOptionProduct);

                // If it is a default product, the product price is included in the car's base price
                if (availableOption.DefaultProductIds.Contains(userSelectedProduct.Id))
                {
                    continue;
                }

                optionsPrice += PriceHelper.GetGrossPrice(userSelectedProduct.NetPrice, userSelectedProduct.VATRate);
            }

            var totalPrice = basePrice + optionsPrice;

            var summary =
                new CarConfiguratorSummary(code, basePrice, totalPrice, optionsPrice, carModelEAN,
                                           validatedSelectedOptionProducts);

            var userConfiguration = SaveConfiguration(summary);

            summary.Code = userConfiguration.Code;

            return(summary);
        }