protected virtual Expression VisitStringQxMethodCall(MethodCallExpression e)
        {
            var member = e.GetRightMostMember();

            var expressionIsNotForMember = member == null || member.Expression.NodeType == ExpressionType.Constant;

            if (expressionIsNotForMember)
            {
                return(Visit(Expression.Constant(e.Evaluate())));
            }

            var methodName = e.Method.Name;

            switch (methodName)
            {
            case "QxContains":
                Nodes.AddNode(CreateNewMemberNode(member).ToStringContainsNode(e.Arguments[1].Evaluate().ToStringOrNull()));
                break;

            case "QxStartsWith":
                Nodes.AddNode(CreateNewMemberNode(member).ToStringStartsWithNode(e.Arguments[1].Evaluate().ToStringOrNull()));
                break;

            case "QxEndsWith":
                Nodes.AddNode(CreateNewMemberNode(member).ToStringEndsWithNode(e.Arguments[1].Evaluate().ToStringOrNull()));
                break;

            case "QxIsExactly":
                Nodes.AddNode(CreateNewMemberNode(member).ToStringExactNode(e.Arguments[1].Evaluate().ToStringOrNull()));
                break;

            case "QxLike":
                Nodes.AddNode(CreateNewMemberNode(member).ToLikeNode(e.Arguments[1].Evaluate().ToStringOrNull()));
                break;

            case "QxToLower":
                Nodes.AddNode(CreateNewMemberNode(member).ToLowerNode());
                break;

            case "QxToUpper":
                Nodes.AddNode(CreateNewMemberNode(member).ToUpperNode());
                break;

            default:
                throw new SisoDbNotSupportedException("String query extension (Qx) method '{0}', is not supported.".Inject(methodName));
            }

            return(e);
        }
        protected virtual Expression VisitSingleValueTypeQxMethodCall(MethodCallExpression e)
        {
            var member     = e.GetRightMostMember();
            var methodName = e.Method.Name;

            switch (methodName)
            {
            case "QxIn":
                Nodes.AddNode(CreateNewMemberNode(member).ToInSetNode(e.Arguments[1].Evaluate() as IEnumerable));
                break;

            default:
                throw new SisoDbNotSupportedException("Single value type query extension (Qx) method '{0}', is not supported.".Inject(methodName));
            }

            return(e);
        }
        protected virtual Expression VisitStringMethodCall(MethodCallExpression e)
        {
            var member = e.GetRightMostMember();

            var expressionIsNotForMember = member == null || member.Expression.NodeType == ExpressionType.Constant;

            if (expressionIsNotForMember)
            {
                return(Visit(Expression.Constant(e.Evaluate())));
            }

            var methodName = e.Method.Name;

            switch (methodName)
            {
            case "Contains":
                Nodes.AddNode(CreateNewMemberNode(member).ToStringContainsNode(e.Arguments[0].Evaluate().ToStringOrNull()));
                break;

            case "StartsWith":
                Nodes.AddNode(CreateNewMemberNode(member).ToStringStartsWithNode(e.Arguments[0].Evaluate().ToStringOrNull()));
                break;

            case "EndsWith":
                Nodes.AddNode(CreateNewMemberNode(member).ToStringEndsWithNode(e.Arguments[0].Evaluate().ToStringOrNull()));
                break;

            case "ToLower":
                Nodes.AddNode(CreateNewMemberNode(member).ToLowerNode());
                break;

            case "ToUpper":
                Nodes.AddNode(CreateNewMemberNode(member).ToUpperNode());
                break;
            }

            return(e);
        }