public override Expression VisitExpression(Expression expression)
        {
            try
            {
                var projectConstantsInHql = _stateStack.Peek() ||
                                            expression != null && IsRegisteredFunction(expression);

                // Set some flags, unless we already have proper values for them:
                //    projectConstantsInHql if they are inside a method call executed server side.
                //    ContainsUntranslatedMethodCalls if a method call must be executed locally.
                var isMethodCall = expression != null && expression.NodeType == ExpressionType.Call;
                if (isMethodCall && (!projectConstantsInHql || !ContainsUntranslatedMethodCalls))
                {
                    var isRegisteredFunction = IsRegisteredFunction(expression);
                    projectConstantsInHql           = projectConstantsInHql || isRegisteredFunction;
                    ContainsUntranslatedMethodCalls = ContainsUntranslatedMethodCalls || !isRegisteredFunction;
                }

                _stateStack.Push(projectConstantsInHql);

                if (expression == null)
                {
                    return(null);
                }

                bool saveCanBeCandidate = _canBeCandidate;

                _canBeCandidate = true;

                if (CanBeEvaluatedInHqlStatementShortcut(expression))
                {
                    HqlCandidates.Add(expression);
                    return(expression);
                }

                base.VisitExpression(expression);

                if (_canBeCandidate)
                {
                    if (CanBeEvaluatedInHqlSelectStatement(expression, projectConstantsInHql))
                    {
                        HqlCandidates.Add(expression);
                    }
                    else
                    {
                        _canBeCandidate = false;
                    }
                }

                _canBeCandidate = _canBeCandidate & saveCanBeCandidate;
            }
            finally
            {
                _stateStack.Pop();
            }

            return(expression);
        }
        public override Expression Visit(Expression expression)
        {
            if (expression == null)
            {
                return(null);
            }

            if (expression is NhNominatedExpression nominatedExpression)
            {
                // Add the nominated clause and strip the nominator wrapper from the select expression
                var innerExpression = nominatedExpression.Expression;
                HqlCandidates.Add(innerExpression);
                return(innerExpression);
            }

            var projectConstantsInHql = _stateStack.Peek() || expression.NodeType == ExpressionType.Equal || IsRegisteredFunction(expression);

            // Set some flags, unless we already have proper values for them:
            //    projectConstantsInHql if they are inside a method call executed server side.
            //    ContainsUntranslatedMethodCalls if a method call must be executed locally.
            var isMethodCall = expression.NodeType == ExpressionType.Call;

            if (isMethodCall && (!projectConstantsInHql || !ContainsUntranslatedMethodCalls))
            {
                var isRegisteredFunction = IsRegisteredFunction(expression);
                projectConstantsInHql           = projectConstantsInHql || isRegisteredFunction;
                ContainsUntranslatedMethodCalls = ContainsUntranslatedMethodCalls || !isRegisteredFunction;
            }

            _stateStack.Push(projectConstantsInHql);
            bool saveCanBeCandidate = _canBeCandidate;

            _canBeCandidate = true;

            try
            {
                if (CanBeEvaluatedInHqlStatementShortcut(expression))
                {
                    HqlCandidates.Add(expression);
                    return(expression);
                }

                expression = base.Visit(expression);

                if (_canBeCandidate)
                {
                    if (CanBeEvaluatedInHqlSelectStatement(expression, projectConstantsInHql))
                    {
                        HqlCandidates.Add(expression);
                    }
                    else
                    {
                        _canBeCandidate = false;
                    }
                }
            }
            finally
            {
                _stateStack.Pop();
                _canBeCandidate = _canBeCandidate && saveCanBeCandidate;
            }

            return(expression);
        }