private static void CheckArgumentExpressionIsValid(Expression expression)
        {
            expression = GetExpressionWithoutConversion(expression);

            if (expression is MemberExpression memberExpression && IsMemberOfA(memberExpression.Member))
            {
                // It's A._, or A.Ignore, so it's safe.
                return;
            }

            var visitor = new ArgumentConstraintExpressionVisitor();

            if (expression is MethodCallExpression methodCallExpression)
            {
                // A method call. It might be A<T>.That.Matches, or one of the other extension methods, so don't
                // check the method node itself. Instead, look at all the arguments (except the first, if it's an
                // extension method).
                int firstArgumentToCheck = IsArgumentConstraintManagerExtensionMethod(methodCallExpression) ? 1 : 0;
                for (var index = firstArgumentToCheck; index < methodCallExpression.Arguments.Count; index++)
                {
                    visitor.Visit(methodCallExpression.Arguments[index]);
                }
            }
            else
            {
                // An unknown kind of expression - could be a constructor, or almost anything else. Play it safe and
                // check it out.
                visitor.Visit(expression);
            }
        }
        private static void CheckArgumentExpressionIsValid(Expression expression)
        {
            expression = GetExpressionWithoutConversion(expression);

            if (expression is MemberExpression memberExpression && IsMemberOfA(memberExpression.Member))
            {
                // It's A._, or A.Ignore, so it's safe.
                return;
            }

            var visitor = new ArgumentConstraintExpressionVisitor();

            if (expression is MethodCallExpression methodCallExpression)
            {
                // A method call. It might be A<T>.That.Matches, or one of the other extension methods, so don't
                // check the method node itself. Instead, look at all the arguments (except the first, if it's an
                // extension method).
                int argumentsToSkip = methodCallExpression.Method.IsDefined(typeof(ExtensionAttribute), false) ? 1 : 0;
                foreach (var argument in methodCallExpression.Arguments.Skip(argumentsToSkip))
                {
                    visitor.Visit(argument);
                }
            }
            else
            {
                // An unknown kind of expression - could be a constructor, or almost anything else. Play it safe and
                // check it out.
                visitor.Visit(expression);
            }
        }