private void VisitQueryableMethodCall(MethodCallExpression expression)
        {
            switch (expression.Method.Name)
            {
            case "OfType":
                VisitExpression(expression.Arguments[0]);
                break;

            case "Where":
            {
                insideWhere++;
                VisitExpression(expression.Arguments[0]);
                if (chainedWhere)
                {
                    luceneQuery.AndAlso();
                }
                if (insideWhere > 1)
                {
                    luceneQuery.OpenSubclause();
                }
                VisitExpression(((UnaryExpression)expression.Arguments[1]).Operand);
                if (insideWhere > 1)
                {
                    luceneQuery.CloseSubclause();
                }
                chainedWhere = true;
                insideWhere--;
                break;
            }

            case "Select":
            {
                VisitExpression(expression.Arguments[0]);
                VisitSelect(((UnaryExpression)expression.Arguments[1]).Operand);
                break;
            }

            case "Skip":
            {
                VisitExpression(expression.Arguments[0]);
                VisitSkip(((ConstantExpression)expression.Arguments[1]));
                break;
            }

            case "Take":
            {
                VisitExpression(expression.Arguments[0]);
                VisitTake(((ConstantExpression)expression.Arguments[1]));
                break;
            }

            case "First":
            case "FirstOrDefault":
            {
                VisitExpression(expression.Arguments[0]);
                if (expression.Arguments.Count == 2)
                {
                    VisitExpression(((UnaryExpression)expression.Arguments[1]).Operand);
                }

                if (expression.Method.Name == "First")
                {
                    VisitFirst();
                }
                else
                {
                    VisitFirstOrDefault();
                }
                break;
            }

            case "Single":
            case "SingleOrDefault":
            {
                VisitExpression(expression.Arguments[0]);
                if (expression.Arguments.Count == 2)
                {
                    VisitExpression(((UnaryExpression)expression.Arguments[1]).Operand);
                }

                if (expression.Method.Name == "Single")
                {
                    VisitSingle();
                }
                else
                {
                    VisitSingleOrDefault();
                }
                break;
            }

            case "All":
            {
                VisitExpression(expression.Arguments[0]);
                VisitAll((Expression <Func <T, bool> >)((UnaryExpression)expression.Arguments[1]).Operand);
                break;
            }

            case "Any":
            {
                VisitExpression(expression.Arguments[0]);
                if (expression.Arguments.Count == 2)
                {
                    VisitExpression(((UnaryExpression)expression.Arguments[1]).Operand);
                }

                VisitAny();
                break;
            }

            case "Count":
            {
                VisitExpression(expression.Arguments[0]);
                if (expression.Arguments.Count == 2)
                {
                    VisitExpression(((UnaryExpression)expression.Arguments[1]).Operand);
                }

                VisitCount();
                break;
            }

            case "Distinct":
                luceneQuery.GroupBy(AggregationOperation.Distinct);
                VisitExpression(expression.Arguments[0]);
                break;

            case "OrderBy":
            case "ThenBy":
            case "ThenByDescending":
            case "OrderByDescending":
                VisitExpression(expression.Arguments[0]);
                VisitOrderBy((LambdaExpression)((UnaryExpression)expression.Arguments[1]).Operand,
                             expression.Method.Name.EndsWith("Descending"));
                break;

            default:
            {
                throw new NotSupportedException("Method not supported: " + expression.Method.Name);
            }
            }
        }