diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erl
index 6324631..ce44fdd 100644
--- a/src/couchdb/couch_httpd_rewrite.erl
+++ b/src/couchdb/couch_httpd_rewrite.erl
@@ -126,8 +126,7 @@ handle_rewrite_req(#httpd{
     % we are in a design handler
     DesignId = <<"_design/", DesignName/binary>>,
     Prefix = <<"/", DbName/binary, "/", DesignId/binary>>,
-    QueryList = couch_httpd:qs(Req),
-    QueryList1 = [{to_binding(K), V} || {K, V} <- QueryList],
+    QueryList = lists:map(fun decode_query_value/1, couch_httpd:qs(Req)),
 
     #doc{body={Props}} = DDoc,
 
@@ -145,7 +144,7 @@ handle_rewrite_req(#httpd{
 
             %% get raw path by matching url to a rule.
             RawPath = case try_bind_path(DispatchList, couch_util:to_binary(Method), PathParts,
-                                    QueryList1) of
+                                    QueryList) of
                 no_dispatch_path ->
                     throw(not_found);
                 {NewPathParts, Bindings} ->
@@ -153,13 +152,15 @@ handle_rewrite_req(#httpd{
 
                     % build new path, reencode query args, eventually convert
                     % them to json
-                    Path = lists:append(
-                        string:join(Parts, [?SEPARATOR]),
-                        case Bindings of
-                            [] -> [];
-                            _ -> [$?, encode_query(Bindings)]
-                        end),
-                    
+                    Bindings1 = maybe_encode_bindings(Bindings),
+                    ?LOG_INFO("bindings1 ~p~n", [Bindings1]),
+                    Path = binary_to_list(
+                        iolist_to_binary([
+                                string:join(Parts, [?SEPARATOR]),
+                                [["?", mochiweb_util:urlencode(Bindings1)] 
+                                    || Bindings1 =/= [] ]
+                            ])),
+
                     % if path is relative detect it and rewrite path
                     case mochiweb_util:safe_relative_path(Path) of
                         undefined ->
@@ -253,44 +254,29 @@ make_query_list([{Key, Value}|Rest], Bindings, Acc) when is_list(Value) ->
 make_query_list([{Key, Value}|Rest], Bindings, Acc) ->
     make_query_list(Rest, Bindings, [{to_binding(Key), Value}|Acc]).
 
-replace_var(Key, Value, Bindings) ->
-    case Value of
-        <<":", Var/binary>> ->
-            get_var(Var, Bindings, Value);
-        <<"*">> ->
-            get_var(Value, Bindings, Value);
-        _ when is_list(Value) ->
-            Value1 = lists:foldr(fun(V, Acc) ->
-                V1 = case V of
-                    <<":", VName/binary>> ->
-                        case get_var(VName, Bindings, V) of
-                            V2 when is_list(V2) ->
-                                iolist_to_binary(V2);
-                            V2 -> V2
-                        end;
-                    <<"*">> ->
-                        get_var(V, Bindings, V);
-                    _ ->
-                        V
-                end,
-                [V1|Acc]
-            end, [], Value),
-            to_json(Value1);
-        _ when is_binary(Value) ->
-            Value;
-        _ ->
-            case Key of
-                <<"key">> -> to_json(Value);
-                <<"startkey">> -> to_json(Value);
-                <<"start_key">> -> to_json(Value);
-                <<"endkey">> -> to_json(Value);
-                <<"end_key">> -> to_json(Value);
-                _ ->
-                    lists:flatten(?JSON_ENCODE(Value))
-            end
+replace_var(Key, <<":", Var/binary>> = Value, Bindings) ->
+    get_var(Var, Bindings, Value);
+replace_var(_Key, Value, Bindings) when is_binary(Value) ->
+    Value;
+replace_var(_Key, Value, Bindings) when is_list(Value) ->
+    lists:foldl(fun
+                (<<":", Var/binary>>=Value1, Acc) ->
+                    [get_var(Var, Bindings, Value1)|Acc];
+                (Value1, Acc) ->
+                    [Value1|Acc]
+            end, [], Value);
+replace_var(Key, Value, _Bindings) ->
+    Value.
+                    
+maybe_json(Key, Value) ->
+    case lists:member(Key, [<<"key">>, <<"startkey">>, <<"start_key">>,
+                <<"endkey">>, <<"end_key">>]) of
+        true ->
+            ?JSON_ENCODE(Value);
+        false ->
+            Value
     end.
 
-
 get_var(VarName, Props, Default) ->
     VarName1 = to_binding(VarName),
     couch_util:get_value(VarName1, Props, Default).
@@ -309,7 +295,7 @@ make_new_path([?MATCH_ALL|_Rest], _Bindings, Remaining, Acc) ->
 make_new_path([{bind, P}|Rest], Bindings, Remaining, Acc) ->
     P2 = case couch_util:get_value({bind, P}, Bindings) of
         undefined -> << "undefined">>;
-        P1 -> P1
+        P1 -> to_json(P1)
     end,
     make_new_path(Rest, Bindings, Remaining, [P2|Acc]);
 make_new_path([P|Rest], Bindings, Remaining, Acc) ->
@@ -437,21 +423,25 @@ path_to_list([P|R], Acc, DotDotCount) ->
     end,
     path_to_list(R, [P1|Acc], DotDotCount).
 
-encode_query(Props) -> 
-    Props1 = lists:foldl(fun ({{bind, K}, V}, Acc) ->
-        case K of
-            <<"*">> -> Acc;
-            _ ->
-                V1 = case is_list(V) orelse is_binary(V) of
-                    true -> V;
-                    false ->
-                        % probably it's a number
-                        quote_plus(V)
-                end,
-                [{K, V1} | Acc]
-        end
-    end, [], Props),
-    lists:flatten(mochiweb_util:urlencode(Props1)).
+maybe_encode_bindings([]) ->
+    [];
+maybe_encode_bindings(Props) -> 
+    lists:foldl(fun 
+            ({{bind, <<"*">>}, V}, Acc) ->
+                Acc;
+            ({{bind, K}, V}, Acc) ->
+                V1 = iolist_to_binary(maybe_json(K, V)),
+                [{K, V1}|Acc]
+        end, [], Props).
+                
+decode_query_value({K,V}) ->
+    case lists:member(K, ["key", "startkey", "start_key",
+                "endkey", "end_key"]) of
+        true ->
+            {to_binding(K), ?JSON_DECODE(V)};
+        false ->
+            {to_binding(K), ?l2b(V)}
+    end.
 
 to_binding({bind, V}) ->
     {bind, V};