public virtual ODataExpression VisitFunctionCall(ODataFunctionCallExpression expr)
        {
            bool updated = false;

            ODataExpression[] args = new ODataExpression[expr.Arguments.Length];
            for (int i = 0; i < expr.Arguments.Length; i++)
            {
                ODataExpression arg = expr.Arguments[i];
                ODataExpression newArg = this.Visit(arg);
                if (newArg != arg)
                {
                    updated = true;
                    args[i] = newArg;
                }
                else
                {
                    args[i] = arg;
                }
            }
            if (updated)
            {
                return new ODataFunctionCallExpression(expr.Name, args);
            }
            return expr;
        }
        public override ODataExpression VisitFunctionCall(ODataFunctionCallExpression expr)
        {
            switch(expr.Name)
            {
                case "substringof":
                    this.sqlBuilder.Append("(");
                    this.Visit(expr.Arguments[1]);
                    this.sqlBuilder.Append(" LIKE ");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append(")");
                    break;
                case "endswith":
                case "startswith":
                    this.sqlBuilder.Append("(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append(" LIKE ");
                    this.Visit(expr.Arguments[1]);
                    this.sqlBuilder.Append(")");
                    break;
                case "length":
                    this.sqlBuilder.Append("(length(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "indexof":
                    this.sqlBuilder.Append("(");
                    this.sqlBuilder.Append("insrt(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append(", ");
                    this.Visit(expr.Arguments[1]);
                    this.sqlBuilder.Append("))");
                    break;
                case "replace":
                    this.sqlBuilder.Append("(");
                    this.sqlBuilder.Append("replace(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append(", ");
                    this.Visit(expr.Arguments[1]);
                    this.sqlBuilder.Append(", ");
                    this.Visit(expr.Arguments[2]);
                    this.sqlBuilder.Append("))");
                    break;
                case "substring":
                    this.sqlBuilder.Append("(");
                    this.sqlBuilder.Append("substr(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append(", ");
                    this.Visit(expr.Arguments[1]);
                    if (expr.Arguments.Length > 2)
                    {
                        this.sqlBuilder.Append(", ");
                        this.Visit(expr.Arguments[2]);
                    }
                    this.sqlBuilder.Append("))");
                    break;
                case "tolower":
                    this.sqlBuilder.Append("(lower(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "toupper":
                    this.sqlBuilder.Append("(upper(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "trim":
                    this.sqlBuilder.Append("(trim(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "concat":
                    this.sqlBuilder.Append("(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append(" || ");
                    this.Visit(expr.Arguments[1]);
                    this.sqlBuilder.Append(")");
                    break;
                    //DATE
                case "day":
                    this.sqlBuilder.Append("(datetime('%d',");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "hour":
                    this.sqlBuilder.Append("(datetime('%H',");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "minute":
                    this.sqlBuilder.Append("(datetime('%M',");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "month":
                    this.sqlBuilder.Append("(datetime('%m',");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "second":
                    this.sqlBuilder.Append("(datetime('%S',");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "year":
                    this.sqlBuilder.Append("(datetime('%Y',");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                //Math
                case "round":
                    this.sqlBuilder.Append("(round(");
                    this.Visit(expr.Arguments[0]);
                    this.sqlBuilder.Append("))");
                    break;
                case "floor":
                case "ceiling":
                    throw new NotSupportedException("SQLite does not support floor or ceiling");
            }

            return expr;
        }