/// <summary>
        /// Visits the expression and generate the lucene query
        /// </summary>
        /// <param name="expression">The expression.</param>
        protected void VisitExpression(Expression expression)
        {
            if (expression is BinaryExpression)
            {
                VisitBinaryExpression((BinaryExpression)expression);
            }
            else
            {
                switch (expression.NodeType)
                {
                case ExpressionType.MemberAccess:
                    VisitMemberAccess((MemberExpression)expression, true);
                    break;

                case ExpressionType.Not:
                    var unaryExpressionOp = ((UnaryExpression)expression).Operand;
                    switch (unaryExpressionOp.NodeType)
                    {
                    case ExpressionType.MemberAccess:
                        VisitMemberAccess((MemberExpression)unaryExpressionOp, false);
                        break;

                    case ExpressionType.Call:
                        // probably a call to !In()
                        luceneQuery.OpenSubclause();
                        luceneQuery.Where("*:*");
                        luceneQuery.NegateNext();
                        VisitMethodCall((MethodCallExpression)unaryExpressionOp);
                        luceneQuery.CloseSubclause();
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(unaryExpressionOp.NodeType.ToString());
                    }
                    break;

                case ExpressionType.Convert:
                case ExpressionType.ConvertChecked:
                    VisitExpression(((UnaryExpression)expression).Operand);
                    break;

                default:
                    if (expression is MethodCallExpression)
                    {
                        VisitMethodCall((MethodCallExpression)expression);
                    }
                    else if (expression is LambdaExpression)
                    {
                        VisitExpression(((LambdaExpression)expression).Body);
                    }
                    break;
                }
            }
        }