internal static Collection <AuthorizationRule> CreateRules(
            XPathNodeIterator rulesNav,
            bool onlyAllowTypeIdSets = false)
        {
            Collection <AuthorizationRule> result =
                new Collection <AuthorizationRule>();

            foreach (XPathNavigator ruleNav in rulesNav)
            {
                AuthorizationRule rule
                    = CreateRule(ruleNav, onlyAllowTypeIdSets);
                if (rule != null)
                {
                    result.Add(rule);
                }
            }

            return(result);
        }
        internal static AuthorizationRule CreateRule(
            XPathNavigator ruleNav,
            bool onlyAllowTypeIdSets)
        {
            bool isOptional = false;

            string isOptionalStr
                = ruleNav.GetAttribute("is-optional", string.Empty);

            if (!string.IsNullOrEmpty(isOptionalStr))
            {
                try
                {
                    isOptional = XmlConvert.ToBoolean(isOptionalStr);
                }
                catch (FormatException)
                {
                }
            }

            string ruleName = ruleNav.GetAttribute("name", string.Empty);

            // <displayflags>
            AuthorizationRuleDisplayFlags displayFlags = AuthorizationRuleDisplayFlags.None;
            XPathNavigator displayFlagsNav             = ruleNav.SelectSingleNode("display-flags");

            if (displayFlagsNav != null)
            {
                try
                {
                    uint flags = XmlConvert.ToUInt32(displayFlagsNav.Value);
                    displayFlags = (AuthorizationRuleDisplayFlags)flags;
                }
                catch (FormatException)
                {
                }
                catch (OverflowException)
                {
                }
            }

            ThingPermissions permissions
                = ThingPermissions.None;
            XPathNodeIterator permissionsIterator =
                ruleNav.Select("permission");

            foreach (XPathNavigator permissionNav in permissionsIterator)
            {
                permissions |=
                    (ThingPermissions)Enum.Parse(
                        typeof(ThingPermissions),
                        permissionNav.Value);
            }

            List <AuthorizationSetDefinition> targetSets =
                GetSets(ruleNav, "target-set");

            List <AuthorizationSetDefinition> exceptionSets =
                GetSets(ruleNav, "exception-set");

            // only do this if only type ID sets are allowed
            //                      AND
            // we have either some target set or exception set data
            // if we enter the if block w/o any target or exception set data to
            // begin with, then we'll incorrectly return <b>null</b> when the XML
            // specified that permissions were allowed on all record data.
            if (onlyAllowTypeIdSets &&
                (targetSets != null || exceptionSets != null))
            {
                if (targetSets != null)
                {
                    for (int i = targetSets.Count - 1; i >= 0; --i)
                    {
                        if (!(targetSets[i] is TypeIdSetDefinition))
                        {
                            targetSets.RemoveAt(i);
                        }
                    }
                }

                if (exceptionSets != null)
                {
                    for (int i = exceptionSets.Count - 1; i >= 0; --i)
                    {
                        if (!(exceptionSets[i] is TypeIdSetDefinition))
                        {
                            exceptionSets.RemoveAt(i);
                        }
                    }
                }

                if ((targetSets == null || targetSets.Count == 0) &&
                    (exceptionSets == null || exceptionSets.Count == 0))
                {
                    return(null);
                }
            }

            AuthorizationRule rule = new AuthorizationRule(
                ruleName,
                null,
                permissions,
                targetSets,
                exceptionSets,
                isOptional,
                displayFlags);

            // <reason>
            // Do this after create the rule so that the CultureSpecificReasons dictionary is available.
            rule.CultureSpecificReasons.PopulateFromXml(ruleNav, "reason");

            return(rule);
        }