/// <summary>
        /// Builds and configures the current page reference
        /// </summary>
        private void Build()
        {
            var        descriptor    = actionContextAccessor.ActionContext.ActionDescriptor as ControllerActionDescriptor;
            MethodInfo currentAction = descriptor.MethodInfo;

            //find the current page in the page tree provider
            CurrentPageTree = FindPageTree(pageTreeProvider.Root, currentAction);


            var      path = new List <PageInfo>();
            PageTree pgt  = CurrentPageTree;

            while (pgt != null)
            {
                //configure the current page with strings from attributes
                ApplyAttributes(pgt);

                //set the path collection for building menus
                path.Add(pgt.Page);
                pgt = pgt.Parent;
            }

            path.Reverse();
            CurrentPagePath = path.AsReadOnly();
        }
        /// <summary>
        /// DFS tree search
        /// </summary>
        /// <param name="tree">Page tree</param>
        /// <param name="action">Action to search</param>
        /// <returns>Node element</returns>
        private PageTree FindPageTree(PageTree tree, MethodInfo action)
        {
            if (tree.Page.Action.Equals(action))
            {
                return(tree);
            }

            foreach (PageTree child in tree.Children)
            {
                PageTree foundChild = FindPageTree(child, action);

                if (foundChild != null)
                {
                    return(foundChild);
                }
            }

            return(null);
        }
        /// <summary>
        /// Configures the localizable strings to the <see cref="PageInfo"/> in the tree path
        /// created from the current request. Uses <see cref="DisplayAttribute"/> and/or the
        /// <see cref="PageMetadataAttribute"/>.
        /// </summary>
        /// <param name="currentPageTree">Current page tree to apply</param>
        private void ApplyAttributes(PageTree currentPageTree)
        {
            PageInfo   currentPage = currentPageTree.Page;
            MethodInfo pageAction  = currentPage.Action;

            //detect and apply the display attribute
            DisplayAttribute displayAttribute = pageAction.GetCustomAttribute <DisplayAttribute>();

            if (displayAttribute != null)
            {
                if (displayAttribute.ResourceType != null)
                {
                    var rs = new ResourceManager(displayAttribute.ResourceType);
                    currentPage.Caption = rs.GetString(displayAttribute.Name);
                }
                else
                {
                    currentPage.Caption = displayAttribute.Name;
                }
            }

            //detect and apply the page metadata attribute
            PageMetadataAttribute pageMetadataAttribute = pageAction.GetCustomAttribute <PageMetadataAttribute>();

            if (pageMetadataAttribute != null)
            {
                if (pageMetadataAttribute.ResourceType != null)
                {
                    var rs = new ResourceManager(pageMetadataAttribute.ResourceType);

                    if (!String.IsNullOrEmpty(pageMetadataAttribute.Caption))
                    {
                        currentPage.Caption = rs.GetString(pageMetadataAttribute.Caption);
                    }

                    if (!String.IsNullOrEmpty(pageMetadataAttribute.Header))
                    {
                        currentPage.Header = rs.GetString(pageMetadataAttribute.Header);
                    }
                }
                else
                {
                    currentPage.Caption = pageMetadataAttribute.Caption;
                    currentPage.Header  = pageMetadataAttribute.Header;
                }

                currentPage.RenderHeader  = pageMetadataAttribute.RenderHeader;
                currentPage.RenderCaption = pageMetadataAttribute.RenderCaption;
            }

            //translate template variables from route data
            if (!String.IsNullOrEmpty(currentPage.Caption))
            {
                currentPage.Caption = TranslateParameters(currentPage.Caption);
            }

            if (!String.IsNullOrEmpty(currentPage.Header))
            {
                currentPage.Header = TranslateParameters(currentPage.Header);
            }

            var urlHelper = new UrlHelper(actionContextAccessor.ActionContext);

            //build url for the items in the page tree using the existing route values
            var routeValues = new Dictionary <string, object>();

            foreach (KeyValuePair <string, object> routeValue in actionContextAccessor.ActionContext.RouteData.Values)
            {
                //detecting a variable template with "{" should be enough
                if (currentPage.UrlTemplate.Contains("{" + routeValue.Key))
                {
                    routeValues.Add(routeValue.Key, routeValue.Value);
                }
            }

            currentPage.CurrentUrl = urlHelper.Action(new UrlActionContext()
            {
                Action     = currentPage.Action.Name,
                Controller = currentPage.Action.DeclaringType.Name.Replace("controller", "", StringComparison.InvariantCultureIgnoreCase),
                Values     = routeValues
            });
        }