anchor.diff:  validate_view_query(extra, _Value, Args) ->
       Args.
   
  -make_view_fold_fun(Req, QueryArgs, Etag, Db, TotalViewCount, HelperFuns) ->
  -    #view_query_args{
  -        end_key = EndKey,
  -        end_docid = EndDocId,
  -        inclusive_end = InclusiveEnd,
  -        direction = Dir
  -    } = QueryArgs,
  -
  -    #view_fold_helper_funs{
  -        passed_end = PassedEndFun,
  -        start_response = StartRespFun,
  -        send_row = SendRowFun,
  -        reduce_count = ReduceCountFun
  -    } = apply_default_helper_funs(HelperFuns,
  -        {Dir, EndKey, EndDocId, InclusiveEnd}),
  -
  -    #view_query_args{
  -        include_docs = IncludeDocs
  -    } = QueryArgs,
  -
  -    fun({{Key, DocId}, Value}, OffsetReds, {AccLimit, AccSkip, Resp, RowFunAcc,
  -                                            OffsetAcc}) ->
  -        PassedEnd = PassedEndFun(Key, DocId),
  -        case {PassedEnd, AccLimit, AccSkip, Resp} of
  -        {true, _, _, _} ->
  -            % The stop key has been passed, stop looping.
  -            % We may need offset so calcluate it here.
  -            % Checking Resp is an optimization that tells
  -            % us its already been calculated (and sent).
  -            NewOffset = case Resp of
  -                undefined -> ReduceCountFun(OffsetReds);
  -                _ -> nil
  -            end,
  -            {stop, {AccLimit, AccSkip, Resp, RowFunAcc, NewOffset}};
  -        {_, 0, _, _} ->
  -            % we've done "limit" rows, stop foldling
  -            {stop, {0, 0, Resp, RowFunAcc, OffsetAcc}};
  -        {_, _, AccSkip, _} when AccSkip > 0 ->
  -            % just keep skipping
  -            {ok, {AccLimit, AccSkip - 1, Resp, RowFunAcc, OffsetAcc}};
  -        {_, _, _, undefined} ->
  -            % rendering the first row, first we start the response
  -            Offset = ReduceCountFun(OffsetReds),
  -            {ok, Resp2, RowFunAcc0} = StartRespFun(Req, Etag,
  -                TotalViewCount, Offset, RowFunAcc),
  -            {Go, RowFunAcc2} = SendRowFun(Resp2, Db, {{Key, DocId}, Value},
  -                IncludeDocs, RowFunAcc0),
  -            {Go, {AccLimit - 1, 0, Resp2, RowFunAcc2, Offset}};
  -        {_, AccLimit, _, Resp} when (AccLimit > 0) ->
  -            % rendering all other rows
  -            {Go, RowFunAcc2} = SendRowFun(Resp, Db, {{Key, DocId}, Value},
  -                IncludeDocs, RowFunAcc),
  -            {Go, {AccLimit - 1, 0, Resp, RowFunAcc2, OffsetAcc}}
  -        end
  -    end.
  -
  -make_reduce_fold_funs(Req, GroupLevel, _QueryArgs, Etag, HelperFuns) ->
  -    #reduce_fold_helper_funs{
  -        start_response = StartRespFun,
  -        send_row = SendRowFun
  -    } = apply_default_helper_funs(HelperFuns),
  -
  -    GroupRowsFun =
  -        fun({_Key1,_}, {_Key2,_}) when GroupLevel == 0 ->
  -            true;
  -        ({Key1,_}, {Key2,_})
  -                when is_integer(GroupLevel) and is_list(Key1) and is_list(Key2) ->
  -            lists:sublist(Key1, GroupLevel) == lists:sublist(Key2, GroupLevel);
  -        ({Key1,_}, {Key2,_}) ->
  -            Key1 == Key2
  -        end,
  -
  -    RespFun = fun
  -    (_Key, _Red, {AccLimit, AccSkip, Resp, RowAcc}) when AccSkip > 0 ->
  -        % keep skipping
  -        {ok, {AccLimit, AccSkip - 1, Resp, RowAcc}};
  -    (_Key, _Red, {0, _AccSkip, Resp, RowAcc}) ->
  -        % we've exhausted limit rows, stop
  -        {stop, {0, _AccSkip, Resp, RowAcc}};
  -
  -    (_Key, Red, {AccLimit, 0, undefined, RowAcc0}) when GroupLevel == 0 ->
  -        % we haven't started responding yet and group=false
  -        {ok, Resp2, RowAcc} = StartRespFun(Req, Etag, RowAcc0),
  -        {Go, RowAcc2} = SendRowFun(Resp2, {null, Red}, RowAcc),
  -        {Go, {AccLimit - 1, 0, Resp2, RowAcc2}};
  -    (_Key, Red, {AccLimit, 0, Resp, RowAcc}) when GroupLevel == 0 ->
  -        % group=false but we've already started the response
  -        {Go, RowAcc2} = SendRowFun(Resp, {null, Red}, RowAcc),
  -        {Go, {AccLimit - 1, 0, Resp, RowAcc2}};
  -
  -    (Key, Red, {AccLimit, 0, undefined, RowAcc0})
  -            when is_integer(GroupLevel), is_list(Key) ->
  -        % group_level and we haven't responded yet
  -        {ok, Resp2, RowAcc} = StartRespFun(Req, Etag, RowAcc0),
  -        {Go, RowAcc2} = SendRowFun(Resp2, {lists:sublist(Key, GroupLevel), Red}, RowAcc),
  -        {Go, {AccLimit - 1, 0, Resp2, RowAcc2}};
  -    (Key, Red, {AccLimit, 0, Resp, RowAcc})
  -            when is_integer(GroupLevel), is_list(Key) ->
  -        % group_level and we've already started the response
  -        {Go, RowAcc2} = SendRowFun(Resp, {lists:sublist(Key, GroupLevel), Red}, RowAcc),
  -        {Go, {AccLimit - 1, 0, Resp, RowAcc2}};
  -
  -    (Key, Red, {AccLimit, 0, undefined, RowAcc0}) ->
  -        % group=true and we haven't responded yet
  -        {ok, Resp2, RowAcc} = StartRespFun(Req, Etag, RowAcc0),
  -        {Go, RowAcc2} = SendRowFun(Resp2, {Key, Red}, RowAcc),
  -        {Go, {AccLimit - 1, 0, Resp2, RowAcc2}};
  -    (Key, Red, {AccLimit, 0, Resp, RowAcc}) ->
  -        % group=true and we've already started the response
  -        {Go, RowAcc2} = SendRowFun(Resp, {Key, Red}, RowAcc),
  -        {Go, {AccLimit - 1, 0, Resp, RowAcc2}}
  -    end,
  -    {ok, GroupRowsFun, RespFun}.
  -
  -apply_default_helper_funs(#view_fold_helper_funs{
  -    passed_end = PassedEnd,
  -    start_response = StartResp,
  -    send_row = SendRow
  -}=Helpers, {Dir, EndKey, EndDocId, InclusiveEnd}) ->
  -    PassedEnd2 = case PassedEnd of
  -    undefined -> make_passed_end_fun(Dir, EndKey, EndDocId, InclusiveEnd);
  -    _ -> PassedEnd
  -    end,
  -
  -    StartResp2 = case StartResp of
  -    undefined -> fun json_view_start_resp/5;
  -    _ -> StartResp
  -    end,
  -
  -    SendRow2 = case SendRow of
  -    undefined -> fun send_json_view_row/5;
  -    _ -> SendRow
  -    end,
  -
  -    Helpers#view_fold_helper_funs{
  -        passed_end = PassedEnd2,
  -        start_response = StartResp2,
  -        send_row = SendRow2
  -    }.
  -
  -apply_default_helper_funs(#reduce_fold_helper_funs{
  -    start_response = StartResp,
  -    send_row = SendRow
  -}=Helpers) ->
  -    StartResp2 = case StartResp of
  -    undefined -> fun json_reduce_start_resp/3;
  -    _ -> StartResp
  -    end,
  -
  -    SendRow2 = case SendRow of
  -    undefined -> fun send_json_reduce_row/3;
  -    _ -> SendRow
  -    end,
  -
  -    Helpers#reduce_fold_helper_funs{
  -        start_response = StartResp2,
  -        send_row = SendRow2
  -    }.
  -
  -make_passed_end_fun(fwd, EndKey, EndDocId, InclusiveEnd) ->
  -    case InclusiveEnd of
  -    true ->
  -        fun(ViewKey, ViewId) ->
  -            couch_view:less_json([EndKey, EndDocId], [ViewKey, ViewId])
  -        end;
  -    false ->
  -        fun
  -            (ViewKey, _ViewId) when ViewKey == EndKey ->
  -                true;
  -            (ViewKey, ViewId) ->
  -                couch_view:less_json([EndKey, EndDocId], [ViewKey, ViewId])
  -        end
  -    end;
  -
  -make_passed_end_fun(rev, EndKey, EndDocId, InclusiveEnd) ->
  -    case InclusiveEnd of
  -    true ->
  -        fun(ViewKey, ViewId) ->
  -            couch_view:less_json([ViewKey, ViewId], [EndKey, EndDocId])
  -        end;
  -    false->
  -        fun
  -            (ViewKey, _ViewId) when ViewKey == EndKey ->
  -                true;
  -            (ViewKey, ViewId) ->
  -                couch_view:less_json([ViewKey, ViewId], [EndKey, EndDocId])
  -        end
  -    end.
  -
  -json_view_start_resp(Req, Etag, TotalViewCount, Offset, _Acc) ->
  -    {ok, Resp} = start_json_response(Req, 200, [{"Etag", Etag}]),
  -    BeginBody = io_lib:format("{\"total_rows\":~w,\"offset\":~w,\"rows\":[\r\n",
  -            [TotalViewCount, Offset]),
  -    {ok, Resp, BeginBody}.
  -
  -send_json_view_row(Resp, Db, {{Key, DocId}, Value}, IncludeDocs, RowFront) ->
  -    JsonObj = view_row_obj(Db, {{Key, DocId}, Value}, IncludeDocs),
  -    send_chunk(Resp, RowFront ++  ?JSON_ENCODE(JsonObj)),
  -    {ok, ",\r\n"}.
  -
  -json_reduce_start_resp(Req, Etag, _Acc0) ->
  -    {ok, Resp} = start_json_response(Req, 200, [{"Etag", Etag}]),
  -    {ok, Resp, "{\"rows\":[\r\n"}.
  -
  -send_json_reduce_row(Resp, {Key, Value}, RowFront) ->
  -    send_chunk(Resp, RowFront ++ ?JSON_ENCODE({[{key, Key}, {value, Value}]})),
  -    {ok, ",\r\n"}.
  -
   view_group_etag(Group, Db) ->
       view_group_etag(Group, Db, nil).
   
  
positive.code: -module(chttpd_view).
  -include_lib("couch/include/couch_db.hrl").
  
  -export([handle_view_req/3,handle_temp_view_req/2]).
  
  -export([get_stale_type/1, get_reduce_type/1, parse_view_params/3]).
  -export([make_view_fold_fun/6, finish_view_fold/3, view_row_obj/3]).
  -export([view_group_etag/2, view_group_etag/3, make_reduce_fold_funs/5]).
  -export([design_doc_view/5, parse_bool_param/1, extract_view_type/3]).
  
  -import(chttpd,
      [send_json/2,send_json/3,send_json/4,send_method_not_allowed/2,send_chunk/2,
  
negative.code:     % they will change the Etag. For more granular Etags we'd need to keep
      % track of the last Db seq that caused an index change.
      chttpd:make_etag({Sig, CurrentSeq, Extra}).
  
  parse_bool_param("true") -> true;
  parse_bool_param("false") -> false;
  