public static NavigationRouteBuilder AddChildRoute <T>(this NavigationRouteBuilder builder, string DisplayText, Expression <Func <T, ActionResult> > action, NavigationRouteOptions options = null) where T : IController
        {
            var childRoute = new NamedRoute("", "", new MvcRouteHandler());

            childRoute.DisplayName = DisplayText;
            childRoute.IsChild     = true;
            childRoute.Options     = options ?? new NavigationRouteOptions();
            childRoute.ToDefaultAction <T>(action, childRoute.Options);
            builder._parent.Children.Add(childRoute);
            builder._routes.Add(childRoute.Name, childRoute);
            return(builder);
        }
        public static NamedRoute ToDefaultAction <T>(this NamedRoute route, Expression <Func <T, ActionResult> > action, NavigationRouteOptions options) where T : IController
        {
            var body = action.Body as MethodCallExpression;

            if (body == null)
            {
                throw new ArgumentException("Expression must be a method call");
            }

            if (body.Object != action.Parameters[0])
            {
                throw new ArgumentException("Method call must target lambda argument");
            }

            string actionName = body.Method.Name;

            // check for ActionName attribute
            var attributes = body.Method.GetCustomAttributes(typeof(ActionNameAttribute), false);

            if (attributes.Length > 0)
            {
                var actionNameAttr = (ActionNameAttribute)attributes[0];
                actionName = actionNameAttr.Name;
            }

            string controllerName = typeof(T).Name;

            if (controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
            {
                controllerName = controllerName.Remove(controllerName.Length - 10, 10);
            }

            ;
            route.Defaults = LinkBuilder.BuildParameterValuesFromExpression(body) ?? new RouteValueDictionary();
            foreach (var pair in route.Defaults.Where(x => x.Value == null).ToList())
            {
                route.Defaults.Remove(pair.Key);
            }

            route.Defaults.Add("controller", controllerName);
            route.Defaults.Add("action", actionName);

            var areaName = options.AreaName;

            route.Url = CreateUrl(actionName, controllerName, areaName);
            //TODO: Add area to route name
            if (areaName == "")
            {
                route.Name = "Navigation-" + controllerName + "-" + actionName;
            }
            else
            {
                route.Name = "Navigation-" + areaName + "-" + controllerName + "-" + actionName;
            }

            if (route.DataTokens == null)
            {
                route.DataTokens = new RouteValueDictionary();
            }
            route.DataTokens.Add("Namespaces", new string[] { typeof(T).Namespace });

            if (!string.IsNullOrEmpty(areaName))
            {
                route.DataTokens.Add("area", areaName.ToLower());
            }
            if (!string.IsNullOrEmpty(options.FilterToken))
            {
                route.DataTokens.Add(Defaults.FILTER_TOKEN_KEY, options.FilterToken.ToLower());
            }

            return(route);
        }
        public static NavigationRouteBuilder MapNavigationRoute <T>(this RouteCollection routes, string displayName, Expression <Func <T, ActionResult> > action, string navigationGroup = "", NavigationRouteOptions options = null) where T : IController
        {
            var newRoute = new NamedRoute("", "", new MvcRouteHandler());

            newRoute.DisplayName     = displayName;
            newRoute.NavigationGroup = navigationGroup;
            newRoute.Options         = options ?? new NavigationRouteOptions();
            newRoute.ToDefaultAction(action, newRoute.Options);
            routes.Add(newRoute.Name, newRoute);
            return(new NavigationRouteBuilder(routes, newRoute));
        }