private static int HashAttributeNode(AttributeFilterNode nodeBuilder)
        {
            var suffix       = nodeBuilder.Wildcard ? "*" : "";
            var stringToHash = nodeBuilder.Key + suffix;

            return(stringToHash.GetHashCode());
        }
        private static AttributeFilterNode MergeAttributeNodes(AttributeFilterNode left, AttributeFilterNode right)
        {
            var key      = left.Wildcard ? left.Key + "*" : left.Key;
            var includes = left.DestinationIncludes | right.DestinationIncludes;
            var excludes = left.DestinationExcludes | right.DestinationExcludes;

            return(new AttributeFilterNode(key, includes, excludes));
        }
        private static bool CanParentAcceptChild(AttributeFilterNode parent, AttributeFilterNode orphan)
        {
            if (!parent.Wildcard)
            {
                return(false);
            }

            if (!orphan.Key.StartsWith(parent.Key))
            {
                return(false);
            }

            return(true);
        }
        private static int CompareAttributeNodes(AttributeFilterNode left, AttributeFilterNode right)
        {
            // keys are different, just use the key comparison result
            if (left.Key != right.Key)
            {
                return(string.Compare(left.Key, right.Key, StringComparison.Ordinal));
            }

            // keys match and wildcard is the same, the attribute nodes are the same (possibly different rules, will need merging)
            if (left.Wildcard == right.Wildcard)
            {
                return(0);
            }

            // keys match, wildcards differ, the one with the wildcard comes first
            return(left.Wildcard ? -1 : 1);
        }
 private static bool CanNodeHaveChildren(AttributeFilterNode node)
 {
     return(node.Wildcard);
 }