public void DeleteSiteMapItems(
            int siteId, int userId, int itemId,
            bool isDeleteAllVersions)
        {
            if (itemId <= 0)
            {
                throw new ArgumentException("itemId <= 0");
            }

            var item = _siteMapProvider.GetByIds(siteId, true, new[] { itemId })?.FirstOrDefault();

            if (item == null || item.Id == 0)
            {
                throw new InvalidOperationException($"Element {itemId} not found");
            }

            var rootPageId = _siteMapProvider.GetRootPage(siteId)?.Id;

            if (itemId == rootPageId)
            {
                throw new InvalidOperationException("Cannot delete the root page");
            }

            var itemsToDelete = new List <AbstractItemData>();

            var allItems        = _siteMapProvider.GetAllItems(siteId, true, false);
            var pages           = allItems.Where(x => x.IsPage).Select(x => _mapper.Map <PageModel>(x)).OrderBy(x => x.IndexOrder).ToList();
            var widgets         = allItems.Where(x => !x.IsPage).Select(x => _mapper.Map <WidgetModel>(x)).OrderBy(x => x.IndexOrder).ToList();
            var pageStructure   = item.IsPage ? SiteMapStructureBuilder.GetPageSubTree(itemId, pages, widgets) : new List <PageModel>();
            var widgetStructure = !item.IsPage ? SiteMapStructureBuilder.GetWidgetSubTree(itemId, widgets) : new List <WidgetModel>();

            void funcWidgets(List <WidgetModel> items)
            {
                foreach (var i in items)
                {
                    itemsToDelete.AddRange(allItems.Where(x => x.Id == i.Id));

                    if (i.HasChildren)
                    {
                        funcWidgets(i.Children);
                    }
                }
            }

            void func(List <PageModel> items)
            {
                foreach (var i in items)
                {
                    itemsToDelete.AddRange(allItems.Where(x => x.Id == i.Id));

                    if (i.HasContentVersion)
                    {
                        itemsToDelete.AddRange(allItems.Where(x => i.ContentVersions.Any(y => x.Id == y.Id)));
                    }

                    if (i.HasWidgets)
                    {
                        funcWidgets(i.Widgets);
                    }

                    if (i.HasChildren)
                    {
                        func(i.Children);
                    }
                }
            }

            if (isDeleteAllVersions)
            {
                var structuralVersions = allItems.Where(x => x.ParentId == item.ParentId && x.Alias == item.Alias && x.Id != item.Id).ToList();
                foreach (var structuralVersion in structuralVersions)
                {
                    if (!structuralVersion.IsPage)
                    {
                        continue;
                    }
                    var structuralVersionPageStructure = SiteMapStructureBuilder.GetPageSubTree(structuralVersion.Id, pages, widgets);
                    func(structuralVersionPageStructure);
                }
            }

            func(pageStructure);
            funcWidgets(widgetStructure);

            var contentId = _settingsProvider.GetContentId(siteId);

            if (itemsToDelete.Any())
            {
                _qpDataProvider.Delete(siteId, contentId, userId, itemsToDelete);
            }
        }
        public void RemoveSiteMapItems(
            int siteId, int userId, int itemId,
            bool isDeleteAllVersions, bool isDeleteContentVersion, int?contentVersionId)
        {
            if (itemId <= 0)
            {
                throw new ArgumentException("itemId <= 0");
            }
            if (!isDeleteContentVersion && contentVersionId == null)
            {
                throw new InvalidOperationException("Field contentVersionId is required if isDeleteContentVersion is false");
            }

            var item = _siteMapProvider.GetByIds(siteId, false, new[] { itemId })?.FirstOrDefault();

            if (item == null || item.Id == 0)
            {
                throw new InvalidOperationException($"Element {itemId} not found");
            }

            if (contentVersionId.HasValue)
            {
                var contentVersion = _siteMapProvider.GetByIds(siteId, false, new[] { contentVersionId.Value })?.FirstOrDefault();
                if (contentVersion == null || contentVersion.Id == 0)
                {
                    throw new InvalidOperationException($"Element {contentVersionId} not found");
                }
            }

            var rootPageId = _siteMapProvider.GetRootPage(siteId)?.Id;

            if (itemId == rootPageId)
            {
                throw new InvalidOperationException("Cannot delete the root page");
            }

            var itemsToArchive = new List <AbstractItemData>();
            AbstractItemData moveContentVersion = null;

            var allItems        = _siteMapProvider.GetAllItems(siteId, false, false);
            var pages           = allItems.Where(x => x.IsPage).Select(x => _mapper.Map <PageModel>(x)).OrderBy(x => x.IndexOrder).ToList();
            var widgets         = allItems.Where(x => !x.IsPage).Select(x => _mapper.Map <WidgetModel>(x)).OrderBy(x => x.IndexOrder).ToList();
            var pageStructure   = item.IsPage ? SiteMapStructureBuilder.GetPageSubTree(itemId, pages, widgets) : new List <PageModel>();
            var widgetStructure = !item.IsPage ? SiteMapStructureBuilder.GetWidgetSubTree(itemId, widgets) : new List <WidgetModel>();

            void funcWidgets(List <WidgetModel> items)
            {
                foreach (var i in items)
                {
                    itemsToArchive.AddRange(allItems.Where(x => x.Id == i.Id));

                    if (i.HasChildren)
                    {
                        funcWidgets(i.Children);
                    }
                }
            }

            void func(List <PageModel> items)
            {
                foreach (var i in items)
                {
                    itemsToArchive.AddRange(allItems.Where(x => x.Id == i.Id));

                    if (!isDeleteAllVersions & !isDeleteContentVersion)
                    {
                        moveContentVersion = allItems.FirstOrDefault(x => x.Id == contentVersionId);
                        if (moveContentVersion != null && moveContentVersion.VersionOfId != null)
                        {
                            moveContentVersion.Alias       = item.Alias;
                            moveContentVersion.ParentId    = item.ParentId;
                            moveContentVersion.VersionOfId = null;
                        }
                    }
                    else
                    {
                        if (i.HasContentVersion)
                        {
                            itemsToArchive.AddRange(allItems.Where(x => i.ContentVersions.Any(y => x.Id == y.Id)));
                        }
                    }

                    if (i.HasWidgets)
                    {
                        funcWidgets(i.Widgets);
                    }

                    if (i.HasChildren)
                    {
                        func(i.Children);
                    }
                }
            }

            if (isDeleteAllVersions)
            {
                var structuralVersions = allItems.Where(x => x.ParentId == item.ParentId && x.Alias == item.Alias && x.Id != item.Id).ToList();
                foreach (var structuralVersion in structuralVersions)
                {
                    if (!structuralVersion.IsPage)
                    {
                        continue;
                    }
                    var structuralVersionPageStructure = SiteMapStructureBuilder.GetPageSubTree(structuralVersion.Id, pages, widgets);
                    func(structuralVersionPageStructure);
                }
            }

            func(pageStructure);
            funcWidgets(widgetStructure);

            var contentId = _settingsProvider.GetContentId(siteId);

            _qpDataProvider.Remove(siteId, contentId, userId, itemsToArchive, moveContentVersion);
        }