private HqlTreeNode TranslateEqualityComparison(BinaryExpression expression)
        {
            var lhs = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs = VisitExpression(expression.Right).ToArithmeticExpression();

            // Check for nulls on left or right.
            if (VisitorUtil.IsNullConstant(expression.Right))
            {
                rhs = null;
            }

            if (VisitorUtil.IsNullConstant(expression.Left))
            {
                lhs = null;
            }

            if (lhs == null && rhs == null)
            {
                return(_hqlTreeBuilder.True());
            }

            if (lhs == null)
            {
                return(_hqlTreeBuilder.IsNull(rhs));
            }

            if (rhs == null)
            {
                return(_hqlTreeBuilder.IsNull((lhs)));
            }

            var lhsNullable = IsNullable(lhs);
            var rhsNullable = IsNullable(rhs);

            var equality = _hqlTreeBuilder.Equality(lhs, rhs);

            if (!lhsNullable || !rhsNullable)
            {
                return(equality);
            }

            var lhs2 = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs2 = VisitExpression(expression.Right).ToArithmeticExpression();

            return(_hqlTreeBuilder.BooleanOr(
                       equality,
                       _hqlTreeBuilder.BooleanAnd(
                           _hqlTreeBuilder.IsNull(lhs2),
                           _hqlTreeBuilder.IsNull(rhs2))));
        }
        private HqlTreeNode TranslateInequalityComparison(BinaryExpression expression)
        {
            var lhs = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs = VisitExpression(expression.Right).ToArithmeticExpression();

            // Check for nulls on left or right.
            if (VisitorUtil.IsNullConstant(expression.Right))
            {
                rhs = null;
            }
            if (VisitorUtil.IsNullConstant(expression.Left))
            {
                lhs = null;
            }

            if (lhs == null && rhs == null)
            {
                return(_hqlTreeBuilder.False());
            }

            if (lhs == null)
            {
                return(_hqlTreeBuilder.IsNotNull(rhs));
            }

            if (rhs == null)
            {
                return(_hqlTreeBuilder.IsNotNull(lhs));
            }

            var lhsNullable = IsNullable(lhs);
            var rhsNullable = IsNullable(rhs);

            var inequality = _hqlTreeBuilder.Inequality(lhs, rhs);

            if (!lhsNullable && !rhsNullable)
            {
                return(inequality);
            }

            var lhs2 = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs2 = VisitExpression(expression.Right).ToArithmeticExpression();

            HqlBooleanExpression booleanExpression;

            if (lhsNullable && rhsNullable)
            {
                booleanExpression = _hqlTreeBuilder.Inequality(
                    _hqlTreeBuilder.IsNull(lhs2).ToArithmeticExpression(),
                    _hqlTreeBuilder.IsNull(rhs2).ToArithmeticExpression());
            }
            else if (lhsNullable)
            {
                booleanExpression = _hqlTreeBuilder.IsNull(lhs2);
            }
            else
            {
                booleanExpression = _hqlTreeBuilder.IsNull(rhs2);
            }

            return(_hqlTreeBuilder.BooleanOr(inequality, booleanExpression));
        }