protected override Expression VisitBinary(BinaryExpression binary)
        {
            ExpressionType nodeType  = binary.NodeType;
            ExpressionType leftType  = binary.Left.NodeType;
            ExpressionType rightType = binary.Right.NodeType;

            bool paranthesesRequired = nodeType.IsSupported() && (leftType.IsSupported() || rightType.IsSupported());

            if (paranthesesRequired)
            {
                _filter.Append("(");
            }

            // Left part
            if (leftType == ExpressionType.Call)
            {
                if (AppendBinaryCall((MethodCallExpression)binary.Left, nodeType))
                {
                    return(binary);
                }
            }
            else
            {
                AppendBinaryPart(binary.Left, leftType);
            }

            // Comparison
            _filter.AppendFormat(" {0} ", nodeType.Serialize());

            // Right part
            if (rightType == ExpressionType.Call)
            {
                var methodCall = (MethodCallExpression)binary.Right;

                if (AppendBinaryCall(methodCall, nodeType))
                {
                    string message = String.Format(Resources.TranslatorMethodNotSupported, methodCall.Method.Name);
                    throw new ArgumentException(message);
                }
            }
            else
            {
                AppendBinaryPart(binary.Right, rightType);
            }

            if (paranthesesRequired)
            {
                _filter.Append(")");
            }

            return(binary);
        }
        private void AppendBinaryPart(Expression node, ExpressionType type)
        {
            switch (type)
            {
            case ExpressionType.Invoke:
                var invocation = (InvocationExpression)node;
                Visit(invocation.Expression);
                break;

            case ExpressionType.New:
            case ExpressionType.NewArrayInit:
            case ExpressionType.Constant:
                AppendConstant(_constantEvaluator.Evaluate(node));
                break;

            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
                var unary = (UnaryExpression)node;
                AppendConstant(_constantEvaluator.Evaluate(unary.Operand));
                break;

            case ExpressionType.MemberAccess:
                var        member     = (MemberExpression)node;
                Expression expression = member.Expression;
                if (expression != null && expression.NodeType == ExpressionType.Parameter)
                {
                    AppendParameter(node);
                }
                else
                {
                    AppendConstant(node);
                }
                break;

            default:
                // Check whether expression is binary
                if (type.IsSupported())
                {
                    Visit(node);
                }
                else
                {
                    string message = String.Format(Resources.TranslatorMemberNotSupported, type);
                    throw new ArgumentException(message);
                }
                break;
            }
        }
        private void AppendBinaryPart(Expression node, ExpressionType type)
        {
            switch (type)
            {
                case ExpressionType.Invoke:
                    var invocation = (InvocationExpression) node;
                    Visit(invocation.Expression);
                    break;

                case ExpressionType.New:
                case ExpressionType.NewArrayInit:
                case ExpressionType.Constant:
                    AppendConstant(_constantEvaluator.Evaluate(node));
                    break;

                case ExpressionType.Convert:
                case ExpressionType.ConvertChecked:
                    var unary = (UnaryExpression) node;
                    AppendConstant(_constantEvaluator.Evaluate(unary.Operand));
                    break;

                case ExpressionType.MemberAccess:
                    var member = (MemberExpression) node;
                    Expression expression = member.Expression;
                    if (expression != null && expression.NodeType == ExpressionType.Parameter)
                    {
                        AppendParameter(node);
                    }
                    else
                    {
                        AppendConstant(node);
                    }
                    break;

                default:
                    // Check whether expression is binary
                    if (type.IsSupported())
                    {
                        Visit(node);
                    }
                    else
                    {
                        string message = String.Format(Resources.TranslatorMemberNotSupported, type);
                        throw new ArgumentException(message);
                    }
                    break;
            }
        }