/// <summary>
        /// Prepare the logo model
        /// </summary>
        /// <returns>Logo model</returns>
        public virtual async Task <LogoModel> PrepareLogoModelAsync()
        {
            var model = new LogoModel
            {
                StoreName = await _localizationService.GetLocalizedAsync(await _storeContext.GetCurrentStoreAsync(), x => x.Name)
            };

            var cacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.StoreLogoPath
                                                                         , await _storeContext.GetCurrentStoreAsync(), await _themeContext.GetWorkingThemeNameAsync(), _webHelper.IsCurrentConnectionSecured());

            model.LogoPath = await _staticCacheManager.GetAsync(cacheKey, async() =>
            {
                var logo          = string.Empty;
                var logoPictureId = _storeInformationSettings.LogoPictureId;

                if (logoPictureId > 0)
                {
                    logo = await _pictureService.GetPictureUrlAsync(logoPictureId, showDefaultPicture: false);
                }

                if (string.IsNullOrEmpty(logo))
                {
                    //use default logo
                    var pathBase      = _httpContextAccessor.HttpContext.Request.PathBase.Value ?? string.Empty;
                    var storeLocation = _mediaSettings.UseAbsoluteImagePath ? _webHelper.GetStoreLocation() : $"{pathBase}/";
                    logo = $"{storeLocation}Themes/{await _themeContext.GetWorkingThemeNameAsync()}/Content/images/logo.png";
                }

                return(logo);
            });

            return(model);
        }
        /// <summary>
        /// Get the render widget models
        /// </summary>
        /// <param name="widgetZone">Name of widget zone</param>
        /// <param name="additionalData">Additional data object</param>
        /// <returns>
        /// A task that represents the asynchronous operation
        /// The task result contains the list of the render widget models
        /// </returns>
        public virtual async Task <List <RenderWidgetModel> > PrepareRenderWidgetModelAsync(string widgetZone, object additionalData = null)
        {
            var theme = await _themeContext.GetWorkingThemeNameAsync();

            var customer = await _workContext.GetCurrentCustomerAsync();

            var customerRoleIds = await _customerService.GetCustomerRoleIdsAsync(customer);

            var store = await _storeContext.GetCurrentStoreAsync();

            var cacheKey = _staticCacheManager.PrepareKeyForShortTermCache(NopModelCacheDefaults.WidgetModelKey,
                                                                           customerRoleIds, store, widgetZone, theme);

            var cachedModels = await _staticCacheManager.GetAsync(cacheKey, async() =>
                                                                  (await _widgetPluginManager.LoadActivePluginsAsync(customer, store.Id, widgetZone))
                                                                  .Select(widget => new RenderWidgetModel
            {
                WidgetViewComponentName      = widget.GetWidgetViewComponentName(widgetZone),
                WidgetViewComponentArguments = new RouteValueDictionary {
                    ["widgetZone"] = widgetZone
                }
            }));

            //"WidgetViewComponentArguments" property of widget models depends on "additionalData".
            //We need to clone the cached model before modifications (the updated one should not be cached)
            var models = cachedModels.Select(renderModel => new RenderWidgetModel
            {
                WidgetViewComponentName      = renderModel.WidgetViewComponentName,
                WidgetViewComponentArguments = new RouteValueDictionary {
                    ["widgetZone"] = widgetZone, ["additionalData"] = additionalData
                }
            }).ToList();

            return(models);
        }