/// <summary>
 /// Check the user whether has the permission to the sitemap item.
 /// </summary>
 /// <param name="userId"></param>
 /// <param name="siteMapItem"></param>
 /// <returns></returns>
 private bool HasPermission(Guid userId, SiteMapItemConfig siteMapItem)
 {
     if (siteMapItem == null || string.IsNullOrEmpty(siteMapItem.Value)) return true;
     return this.permissionApi.HasPermission(userId, siteMapItem.Value);
 }
        /// <summary>
        /// Filter all sitemap item configs not included in specified user permissions.
        /// </summary>
        /// <param name="siteMapItemConfigEnumerable"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        private IEnumerable<SiteMapItemConfig> FilterSiteMapItemsByUserPermission(IEnumerable<SiteMapItemConfig> siteMapItemConfigEnumerable, Guid userId)
        {
            List<SiteMapItemConfig> results = new List<SiteMapItemConfig>();

            int totalCount = siteMapItemConfigEnumerable.Count();
            int authenticatedSiteMapItemCount = 0;
            SiteMapItemConfig previousSiteMapItemConfig = null;
            for (int i = 0; i < totalCount; i++)
            {
                SiteMapItemConfig siteMapItemConfig = siteMapItemConfigEnumerable.ElementAt(i);
                bool emptySiteMapItem = Kit.IsEmpty(siteMapItemConfig.Value);
                if (!emptySiteMapItem)
                {
                    // remove an unauthenticated sitemap item with non-empty value.
                    bool authenticatedSiteMapItem = this.HasPermission(userId, siteMapItemConfig);
                    if (!authenticatedSiteMapItem) continue;
                }

                IEnumerable<SiteMapItemConfig> includedSiteMapItemConfigEnumerable = null;
                if (siteMapItemConfig.Item != null && siteMapItemConfig.Item.Length > 0)
                    includedSiteMapItemConfigEnumerable = FilterSiteMapItemsByUserPermission(siteMapItemConfig.Item, userId);

                // remove the "ancestor" sitemap item (SiteMapItem.Value is null or empty) without child
                if (emptySiteMapItem
                    && siteMapItemConfig.Type != SiteMapItemTypes.Separator
                    && (includedSiteMapItemConfigEnumerable == null || includedSiteMapItemConfigEnumerable.Count() == 0))
                {
                    continue;
                }

                SiteMapItemConfig newSiteMapItemConfig = new SiteMapItemConfig
                {
                    Id = siteMapItemConfig.Id,
                    ClientSideCommand = siteMapItemConfig.ClientSideCommand,
                    PageUrl = siteMapItemConfig.PageUrl,
                    IconClassName = siteMapItemConfig.IconClassName,
                    Item = siteMapItemConfig.Item,
                    Text = siteMapItemConfig.Text,
                    Type = siteMapItemConfig.Type,
                    Value = siteMapItemConfig.Value
                };

                // set processed children back to siteMapItemConfig
                newSiteMapItemConfig.Item = (includedSiteMapItemConfigEnumerable != null && includedSiteMapItemConfigEnumerable.Count() > 0) ? includedSiteMapItemConfigEnumerable.ToArray() : null;

                if (newSiteMapItemConfig.Type == SiteMapItemTypes.Separator)
                {
                    // "Separator" never be first
                    if (authenticatedSiteMapItemCount == 0) continue;

                    // no continuous 2 "Separator"
                    if (previousSiteMapItemConfig != null && previousSiteMapItemConfig.Type == SiteMapItemTypes.Separator) continue;

                    // "Separator" never be last
                    if (i == totalCount - 1) continue;
                }

                previousSiteMapItemConfig = newSiteMapItemConfig;
                results.Add(newSiteMapItemConfig);
                authenticatedSiteMapItemCount++;
            }

            return results;
        }