/// <summary>
        /// Checks whether the supplied <paramref name="method"/> matches the <paramref name="rule"/>.
        /// </summary>
        /// <param name="rule">The rule to match against the <paramref name="method"/>.</param>
        /// <param name="type">The type to check if it matches the <paramref name="rule"/> if
        /// <see cref="RegexRule.Type"/> is not null.</param>
        /// <param name="method">The method to check if it matches the <paramref name="rule"/>.</param>
        /// <returns><see langword="true"/> if the <paramref name="rule"/> matches against the
        /// <paramref name="method"/>; otherwise <see langword="false"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="rule"/>, <paramref name="type"/> or
        /// <paramref name="method"/> parameters are <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">The <see cref="RegexRule.Method"/> property of the
        /// <paramref name="rule"/> is <see langword="null"/>.</exception>
        public static bool MatchMethod(this RegexRule rule, Type type, MethodBase method)
        {
            if (rule == null)
            {
                throw new ArgumentNullException(nameof(rule));
            }
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }
            if (rule.Method == null)
            {
                throw new ArgumentException("The rule has a null Method regular expression.", nameof(rule));
            }

            // If there is a type regular expression it must match the type.
            if (rule.Type != null && !rule.MatchType(type))
            {
                return(false);
            }

            return(rule.Method.IsMatch(method.Name));
        }
// ReSharper disable UnusedParameter.Local
        private void AssertMethodRule(Func <string, Type, IRegexFilter> addMethod, MethodBase method, Type type, bool expectedInclude)
        {
            IRegexFilter actualFilter = addMethod(method.Name, type);

            int expectedRules = 1;

            if (expectedInclude && type != null)
            {
                expectedRules++;
            }

            Assert.Same(addMethod.Target, actualFilter);
            Assert.Equal(expectedRules, actualFilter.Rules.Count);
            RegexRule addedRule = actualFilter.MethodRules.Single();

            Assert.Equal(expectedInclude, addedRule.Include);
            Assert.NotNull(addedRule.Method);
            Assert.True(addedRule.MatchMethod(type ?? GetType(), method));
            Assert.Null(addedRule.Parameter);

            if (type == null)
            {
                Assert.Null(addedRule.Type);
            }
            else
            {
                Assert.NotNull(addedRule.Type);
                Assert.True(addedRule.MatchType(type));
            }
        }
        public void ThrowIfNoTypeRuleForTypeMatch(Type type)
        {
            // Arrange
            var rule = new RegexRule("Throw rule");

            // Act/Assert
            string paramName = Assert.Throws<ArgumentException>(() => rule.MatchType(type)).ParamName;
            Assert.Equal("rule", paramName);
        }
        public void ThrowIfNoTypeRuleForTypeMatch(Type type)
        {
            // Arrange
            var rule = new RegexRule("Throw rule");

            // Act/Assert
            string paramName = Assert.Throws <ArgumentException>(() => rule.MatchType(type)).ParamName;

            Assert.Equal("rule", paramName);
        }
        public void NotMatchAType(Type type)
        {
            // Arrange
            var rule = new RegexRule("Miss rule", type: new Regex("Miss"));

            // Act
            bool actual = rule.MatchType(type);

            // Assert
            Assert.False(actual);
        }
        public void NotMatchAType(Type type)
        {
            // Arrange
            var rule = new RegexRule("Miss rule", type: new Regex("Miss"));

            // Act
            bool actual = rule.MatchType(type);

            // Assert
            Assert.False(actual);
        }
        public void MatchAType(Type type)
        {
            // Arrange
            var rule = new RegexRule(
                type.Name + " hit rule",
                include: true,
                type: new Regex(@".+\." + type.Name));

            // Act
            bool actual = rule.MatchType(type);

            // Assert
            Assert.True(actual);
        }
        public void MatchAType(Type type)
        {
            // Arrange
            var rule = new RegexRule(
                type.Name + " hit rule",
                include: true,
                type: new Regex(@".+\." + type.Name));

            // Act
            bool actual = rule.MatchType(type);

            // Assert
            Assert.True(actual);
        }
// ReSharper disable UnusedParameter.Local
        private void AssertTypeRule(Func <Type, IRegexFilter> addMethod, bool expectedInclude)
        {
            IRegexFilter actualFilter = addMethod(GetType());

            Assert.Same(addMethod.Target, actualFilter);
            Assert.Single(actualFilter.Rules);
            RegexRule addedRule = actualFilter.Rules.Single();

            Assert.Equal(expectedInclude, addedRule.Include);
            Assert.NotNull(addedRule.Type);
            Assert.Null(addedRule.Method);
            Assert.Null(addedRule.Parameter);
            Assert.True(addedRule.MatchType(GetType()));
        }
// ReSharper disable UnusedParameter.Local
        private void AssertParameterRule(Func <string, Type, string, IRegexFilter> addMethod, ParameterInfo parameter, Type type, MethodBase method, bool expectedInclude)
        {
            IRegexFilter actualFilter = addMethod(parameter.Name, type, method == null ? null : method.Name);

            int expectedRules = 1;

            if (expectedInclude && method != null)
            {
                expectedRules++;
            }
            if (expectedInclude && type != null)
            {
                expectedRules++;
            }

            Assert.Same(addMethod.Target, actualFilter);
            Assert.Equal(expectedRules, actualFilter.Rules.Count);
            RegexRule addedRule = actualFilter.ParameterRules.Single();

            Assert.Equal(expectedInclude, addedRule.Include);
            Assert.NotNull(addedRule.Parameter);
            Assert.True(addedRule.MatchParameter(type ?? GetType(), method ?? new Mock <MethodBase>().Object, parameter));

            if (type == null)
            {
                Assert.Null(addedRule.Type);
            }
            else
            {
                Assert.NotNull(addedRule.Type);
                Assert.True(addedRule.MatchType(type));
            }

            if (method == null)
            {
                Assert.Null(addedRule.Method);
            }
            else
            {
                Assert.NotNull(addedRule.Method);
                Assert.True(addedRule.MatchMethod(type ?? GetType(), method));
            }
        }
        /// <summary>
        /// Checks whether the supplied <paramref name="parameter"/> matches the <paramref name="rule"/>.
        /// </summary>
        /// <param name="rule">The rule to match against the <paramref name="method"/>.</param>
        /// <param name="type">The type to check if it matches the <paramref name="rule"/> if
        /// <see cref="RegexRule.Type"/> is not null.</param>
        /// <param name="method">The method to check if it matches the <paramref name="rule"/> if
        /// <see cref="RegexRule.Method"/> is not null.</param>
        /// <param name="parameter">The parameter to check if it matches the <paramref name="rule"/>.</param>
        /// <returns><see langword="true"/> if the <paramref name="rule"/> matches against the
        /// <paramref name="parameter"/>; otherwise <see langword="false"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="rule"/>, <paramref name="type"/>,
        /// <paramref name="method"/> or <paramref name="parameter"/> parameters are <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">The <see cref="RegexRule.Parameter"/> property of the
        /// <paramref name="rule"/> is <see langword="null"/>.</exception>
        public static bool MatchParameter(this RegexRule rule, Type type, MethodBase method, ParameterInfo parameter)
        {
            if (rule == null)
            {
                throw new ArgumentNullException(nameof(rule));
            }
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }
            if (rule.Parameter == null)
            {
                throw new ArgumentException("The rule has a null Parameter regular expression.", nameof(rule));
            }

            // If there is a method regular expression it must match the method.
            if (rule.Method != null)
            {
                if (!rule.MatchMethod(type, method))
                {
                    return(false);
                }
            }
            else if (rule.Type != null && !rule.MatchType(type))
            {
                // If there is a type regular expression but no method it must match the type.
                return(false);
            }

            return(rule.Parameter.IsMatch(parameter.Name));
        }