public override Expression VisitExpression(
            [NotNull]Expression expression)
        {
            var currentExpression = expression;
            var inExpressionOptimized = 
                new EqualityPredicateInExpressionOptimizer().VisitExpression(currentExpression);

            if (inExpressionOptimized != null)
            {
                currentExpression = inExpressionOptimized;
            }

            var equalityExpanded = 
                new EqualityPredicateExpandingVisitor().VisitExpression(currentExpression);

            if (equalityExpanded != null)
            {
                currentExpression = equalityExpanded;
            }

            var negationOptimized =
                new PredicateNegationExpressionOptimizer().VisitExpression(currentExpression);

            if (negationOptimized != null)
            {
                currentExpression = negationOptimized;
            }

            return currentExpression;
        }
        public override Expression VisitExpression(
            [NotNull] Expression expression)
        {
            var currentExpression     = expression;
            var inExpressionOptimized =
                new EqualityPredicateInExpressionOptimizer().VisitExpression(currentExpression);

            if (inExpressionOptimized != null)
            {
                currentExpression = inExpressionOptimized;
            }

            var equalityExpanded =
                new EqualityPredicateExpandingVisitor().VisitExpression(currentExpression);

            if (equalityExpanded != null)
            {
                currentExpression = equalityExpanded;
            }

            var negationOptimized =
                new PredicateNegationExpressionOptimizer().VisitExpression(currentExpression);

            if (negationOptimized != null)
            {
                currentExpression = negationOptimized;
            }

            return(currentExpression);
        }
        public override Expression VisitExpression(
            [NotNull] Expression expression)
        {
            var currentExpression     = expression;
            var inExpressionOptimized =
                new EqualityPredicateInExpressionOptimizer().VisitExpression(currentExpression);

            currentExpression = inExpressionOptimized;

            var negationOptimized1 =
                new PredicateNegationExpressionOptimizer()
                .VisitExpression(currentExpression);

            currentExpression = negationOptimized1;

            var equalityExpanded =
                new EqualityPredicateExpandingVisitor().VisitExpression(currentExpression);

            currentExpression = equalityExpanded;

            var negationOptimized2 =
                new PredicateNegationExpressionOptimizer()
                .VisitExpression(currentExpression);

            currentExpression = negationOptimized2;

            var parameterDectector = new ParameterExpressionDetectingVisitor();

            parameterDectector.VisitExpression(currentExpression);

            if (!parameterDectector.ContainsParameters && !_useRelationalNullSemantics)
            {
                var optimizedNullExpansionVisitor  = new NullSemanticsOptimizedExpandingVisitor();
                var nullSemanticsExpandedOptimized = optimizedNullExpansionVisitor.VisitExpression(currentExpression);
                if (optimizedNullExpansionVisitor.OptimizedExpansionPossible)
                {
                    currentExpression = nullSemanticsExpandedOptimized;
                }
                else
                {
                    currentExpression = new NullSemanticsExpandingVisitor()
                                        .VisitExpression(currentExpression);
                }
            }

            if (_useRelationalNullSemantics)
            {
                currentExpression = new NotNullableExpression(currentExpression);
            }

            var negationOptimized3 =
                new PredicateNegationExpressionOptimizer()
                .VisitExpression(currentExpression);

            currentExpression = negationOptimized3;

            return(currentExpression);
        }
        public override Expression VisitExpression(
            [NotNull] Expression expression)
        {
            var currentExpression = expression;
            var inExpressionOptimized =
                new EqualityPredicateInExpressionOptimizer().VisitExpression(currentExpression);

            currentExpression = inExpressionOptimized;

            var negationOptimized1 =
                new PredicateNegationExpressionOptimizer()
                    .VisitExpression(currentExpression);

            currentExpression = negationOptimized1;

            var equalityExpanded =
                new EqualityPredicateExpandingVisitor().VisitExpression(currentExpression);

            currentExpression = equalityExpanded;

            var negationOptimized2 =
                new PredicateNegationExpressionOptimizer()
                    .VisitExpression(currentExpression);

            currentExpression = negationOptimized2;

            var parameterDectector = new ParameterExpressionDetectingVisitor();
            parameterDectector.VisitExpression(currentExpression);

            if (!parameterDectector.ContainsParameters && !_useRelationalNullSemantics)
            {
                var optimizedNullExpansionVisitor = new NullSemanticsOptimizedExpandingVisitor();
                var nullSemanticsExpandedOptimized = optimizedNullExpansionVisitor.VisitExpression(currentExpression);
                if (optimizedNullExpansionVisitor.OptimizedExpansionPossible)
                {
                    currentExpression = nullSemanticsExpandedOptimized;
                }
                else
                {
                    currentExpression = new NullSemanticsExpandingVisitor()
                        .VisitExpression(currentExpression);
                }
            }

            if (_useRelationalNullSemantics)
            {
                currentExpression = new NotNullableExpression(currentExpression);
            }

            var negationOptimized3 =
                new PredicateNegationExpressionOptimizer()
                    .VisitExpression(currentExpression);

            currentExpression = negationOptimized3;

            return currentExpression;
        }