public List <WidgetModel> GetWidgetItems(int siteId, bool isArchive, int parentId, int[] regionIds = null, bool?useHierarchyRegionFilter = null)
        {
            Func <AbstractItemData, bool> regionFilter = x => true;
            var useRegion = _settingsProvider.HasRegion(siteId);

            if (useRegion)
            {
                _logger.LogTrace("Use region filter");
                var rootPage = _siteMapProvider.GetRootPage(siteId);
                var regions  = _dictionaryProvider.GetAllRegions(siteId);
                var filter   = RegionFilterFactory.Create(rootPage, regions, useHierarchyRegionFilter ?? false);
                regionFilter = filter.GetFilter(regionIds);
            }

            var iconUrl = _settingsProvider.GetIconUrl(siteId);

            var items = _widgetProvider.GetItems(siteId, isArchive, new[] { parentId })
                        .Where(regionFilter)
                        .Select(x => _mapper.Map <WidgetModel>(x))
                        .ToList();
            // items.ForEach(x => x.IconUrl = $"{iconUrl}/{x.IconUrl}");
            var children = _widgetProvider.GetItems(siteId, isArchive, items.Select(x => x.Id))
                           .Where(regionFilter)
                           .Select(x => _mapper.Map <WidgetModel>(x))
                           .ToList();

            // children.ForEach(x => x.IconUrl = $"{iconUrl}/{x.IconUrl}");

            foreach (var item in items)
            {
                item.Children = children.Where(x => x.ParentId == item.Id).ToList();
            }

            return(items);
        }
        public PageModel GetSiteMapSubTree(int siteId, int itemId, int[] regionIds = null, bool?useHierarchyRegionFilter = null)
        {
            _logger.LogTrace($"GetSiteMapSubStructure siteId={siteId}, regionIds={string.Join(", ", regionIds)}, useHierarchyRegionFilter={useHierarchyRegionFilter}");
            Func <AbstractItemData, bool> regionFilter = x => true;
            var useRegion = _settingsProvider.HasRegion(siteId);

            if (useRegion)
            {
                _logger.LogTrace("Use region filter");
                var rootPage = _siteMapProvider.GetRootPage(siteId);
                var regions  = _dictionaryProvider.GetAllRegions(siteId);
                var filter   = RegionFilterFactory.Create(rootPage, regions, useHierarchyRegionFilter ?? false);
                regionFilter = filter.GetFilter(regionIds);
            }

            var iconUrl = _settingsProvider.GetIconUrl(siteId);

            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var abstractItems = _siteMapProvider.GetAllItems(siteId, false, useRegion)
                                .Where(regionFilter)
                                .ToList();

            // abstractItems.ForEach(x => x.IconUrl = $"{iconUrl}/{x.IconUrl}");
            stopwatch.Stop();
            _logger.LogTrace($"get all abstract items {stopwatch.ElapsedMilliseconds}ms");

            stopwatch.Reset();
            stopwatch.Start();

            var pages   = abstractItems.Where(x => x.IsPage).Select(x => _mapper.Map <PageModel>(x)).OrderBy(x => x.IndexOrder).ToList();
            var widgets = abstractItems.Where(x => !x.IsPage).Select(x => _mapper.Map <WidgetModel>(x)).OrderBy(x => x.IndexOrder).ToList();

            var result = SiteMapStructureBuilder.GetPageSubTree(itemId, pages, widgets);

            stopwatch.Stop();
            _logger.LogTrace($"convert abstract items to tree {stopwatch.ElapsedMilliseconds}ms");

            return(result.FirstOrDefault());
        }