/// <summary>
        /// Navega por todos os elementos filhos do pai.
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        private static IEnumerable <XmlAuthorizationPath> Navigate(XmlAuthorizationPath parent)
        {
            foreach (var i in parent.Children)
            {
                yield return(i);

                foreach (var x in Navigate(i))
                {
                    yield return(x);
                }
            }
        }
        /// <summary>
        /// Pesquisa os caminhos aplicando um filtro.
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        private static IEnumerable <XmlAuthorizationPath> Where(XmlAuthorizationPath parent, Func <XmlAuthorizationPath, bool> filter)
        {
            foreach (var i in parent.Children)
            {
                if (filter(i))
                {
                    yield return(i);

                    foreach (var x in Navigate(i))
                    {
                        yield return(x);
                    }
                }
            }
        }
        public override AuthorizationRuleCollection GetAllRulesByPath(string path)
        {
            string loc                     = FormatVirtualPath(path);
            var    validPathsQueue         = new Queue <XmlAuthorizationPath>();
            XmlAuthorizationPath validPath = null;
            var queuePaths                 = new Queue <XmlAuthorizationPath>();

            queuePaths.Enqueue(Root);
            while (queuePaths.Count > 0)
            {
                var p1 = queuePaths.Dequeue();
                foreach (var i in p1.Children.ToArray())
                {
                    if (i == null)
                    {
                        continue;
                    }
                    if ((i.Complex != null && i.Complex.Match(loc).Success) || (loc.Length >= i.FullUrl.Length && loc.IndexOf(i.FullUrl, 0, i.FullUrl.Length, StringComparison.InvariantCultureIgnoreCase) == 0 && (validPath == null || i.FullUrl.Length > validPath.FullUrl.Length)))
                    {
                        validPathsQueue.Enqueue(i);
                        validPath = i;
                        queuePaths.Enqueue(i);
                    }
                }
                if (p1 == null)
                {
                    break;
                }
            }
            var result = new AuthorizationRuleCollection();

            foreach (var i in validPathsQueue)
            {
                foreach (var j in i.GetRules())
                {
                    result.Add(j);
                }
            }
            return(result);
        }
     /// <summary>
     /// Recupera as regras equivalentes.
     /// </summary>
     /// <param name="path"></param>
     /// <param name="type"></param>
     /// <returns></returns>
     public IEnumerable <AuthorizationRule> GetAuthorizationRules(XmlAuthorizationPath path)
     {
         if (Users.Count > 0)
         {
             yield return new AuthorizationRule {
                        Path              = path.FullUrl,
                        Action            = Action,
                        Type              = AuthorizationRuleType.Users,
                        Status            = true,
                        Data              = Users,
                        LoginPageRedirect = LoginPageRedirect
             }
         }
         ;
         if (Roles.Count > 0)
         {
             yield return new AuthorizationRule {
                        Path              = path.FullUrl,
                        Action            = Action,
                        Type              = AuthorizationRuleType.Roles,
                        Status            = true,
                        Data              = Roles,
                        LoginPageRedirect = LoginPageRedirect
             }
         }
         ;
         if (HttpVerbs.Count > 0)
         {
             yield return new AuthorizationRule {
                        Path              = path.FullUrl,
                        Action            = Action,
                        Type              = AuthorizationRuleType.HttpVerbs,
                        Status            = true,
                        Data              = HttpVerbs,
                        LoginPageRedirect = LoginPageRedirect
             }
         }
         ;
     }
 }
        /// <summary>
        /// Construtor padrĂ£o.
        /// </summary>
        /// <param name="parent">Elemento pai.</param>
        /// <param name="element"></param>
        public XmlAuthorizationPath(XmlAuthorizationPath parent, XmlElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }
            Parent   = parent;
            Children = new List <XmlAuthorizationPath>();
            Url      = element.GetAttribute("url");
            FullUrl  = (parent != null && !string.IsNullOrEmpty(parent.FullUrl) ? parent.FullUrl + "/" : "") + Url;
            var complexParts = Regex.Matches(FullUrl, "{[0-9]*?}", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);

            if (complexParts.Count > 0)
            {
                var complexRegex = FullUrl;
                var partNumber   = 0;
                foreach (Match i in complexParts)
                {
                    complexRegex = complexRegex.Replace(i.Value, "(?<complex" + (partNumber++) + ">[\\s\\S]*?)");
                }
                Complex = new Regex(complexRegex);
            }
            if (element.HasChildNodes)
            {
                foreach (var i in element.ChildNodes)
                {
                    var node = i as XmlElement;
                    if (node == null)
                    {
                        continue;
                    }
                    var name = node.Name.ToLower();
                    if (name == "allow")
                    {
                        Allow = new XmlAuthorizationRule(node);
                        _permissions.Add(Allow);
                    }
                    else if (name == "deny")
                    {
                        Deny = new XmlAuthorizationRule(node);
                        _permissions.Add(Deny);
                    }
                    else if (name == "paths" && node.HasChildNodes)
                    {
                        foreach (var j in node.ChildNodes)
                        {
                            var n1 = j as XmlElement;
                            if (n1.Name.ToLower() == "path")
                            {
                                Children.Add(new XmlAuthorizationPath(this, n1));
                            }
                        }
                    }
                }
            }
            if (Allow == null)
            {
                Allow = new XmlAuthorizationRule(AuthorizationRuleAction.Allow);
            }
            if (Deny == null)
            {
                Deny = new XmlAuthorizationRule(AuthorizationRuleAction.Deny);
            }
        }