anchor.diff:  -include("couch_db.hrl").
   
   -define (MAX_BYTES, 10000000).
  +-define (MAX_CHUNK_SIZE, 65535).
   
   start_link(Parent, Target, Reader, _PostProps) ->
       {ok, spawn_link(fun() -> writer_loop(Parent, Reader, Target) end)}.
   
   make_chunk(Data) when is_list(Data) ->
       make_chunk(list_to_binary(Data));
  +make_chunk(Data) when size(Data) > ?MAX_CHUNK_SIZE ->
  +    <<ChunkData:?MAX_CHUNK_SIZE/binary, Rest/binary>> = Data,
  +    Chunk = {?MAX_CHUNK_SIZE, [ibrowse_lib:dec2hex(4, ?MAX_CHUNK_SIZE), "\r\n",
  +        ChunkData, "\r\n"]},
  +    [Chunk, Rest];
   make_chunk(Data) ->
       Size = size(Data),
  -    {Size, [ibrowse_lib:dec2hex(8, Size), "\r\n", Data, "\r\n"]}.
  +    [{Size, [ibrowse_lib:dec2hex(4, Size), "\r\n", Data, "\r\n"]}].
   
  -upload_docs({start, W, Docs}) ->
  -    {Size, Chunk} = make_chunk(<<"{\"new_edits\":false, \"docs\":[">>),
  -    {ok, Chunk, {continue, W, Docs, "", Size}};
  -upload_docs({continue, W, Docs, _, ByteCount}) when ByteCount > ?MAX_BYTES ->
  -    W ! {docs_remaining, length(Docs)},
  -    {ok, "2\r\n]}\r\n", last_chunk};
  -upload_docs({continue, W, [Doc|Rest], Prepend, ByteCount}) ->
  -    JsonDoc = ?JSON_ENCODE(couch_doc:to_json_obj(Doc, [revs,attachments])),
  -    {Size, Chunk} = make_chunk([Prepend, JsonDoc]),
  -    {ok, Chunk, {continue, W, Rest, ",", ByteCount+Size}};
  -upload_docs({continue, W, [], _, _}) ->
  -    W ! {docs_remaining, 0},
  -    {ok, "2\r\n]}\r\n", last_chunk};
  -upload_docs(last_chunk) ->
  -    {ok, "0\r\n\r\n", finish};
  +upload_docs({start, Buffer}) ->
  +    [{Size, Chunk}] = make_chunk(<<"{\"new_edits\":false, \"docs\":[">>),
  +    % Buffer ! {self(), next_doc},
  +    {ok, Chunk, {continue, Buffer, "", Size}};
  +
  +upload_docs({continue, _Buf, _Pre, ByteCount}) when ByteCount > ?MAX_BYTES ->
  +    {ok, "2\r\n]}\r\n0\r\n\r\n", finish};
  +upload_docs({continue, Buffer, Prepend, ByteCount}) ->
  +    Buffer ! {self(), next_doc},
  +    receive 
  +    {ok, JsonDoc} ->
  +        [{Size, Chunk} | MoreData] = make_chunk([Prepend, JsonDoc]),
  +        {ok, Chunk, {multi_chunk, MoreData, Buffer, ",", ByteCount+Size}};
  +    eof ->
  +        {ok, "2\r\n]}\r\n0\r\n\r\n", finish};
  +    timeout ->
  +        ?LOG_DEBUG("sending a heartbeat to keep the connection open", []),
  +        {ok, "1\r\n \r\n", {continue, Buffer, Prepend, ByteCount}}
  +    end;
  +
  +upload_docs({multi_chunk, [], Buffer, Prepend, ByteCount}) ->
  +    % Buffer ! {self(), next_doc},
  +    upload_docs({continue, Buffer, Prepend, ByteCount});
  +upload_docs({multi_chunk, [Data], Buffer, Prepend, ByteCount}) ->
  +    [{Size, Chunk} | MoreData] = make_chunk(Data),
  +    {ok, Chunk, {multi_chunk, MoreData, Buffer, Prepend, ByteCount+Size}};
  +
   upload_docs(finish) ->
       couch_util:should_flush(),
       eof.
  -    
  +
  +encoding_worker([]) ->
  +    receive {MiddleMan, next_doc} -> MiddleMan ! eof end,
  +    ok;
  +encoding_worker([Doc|Rest]) ->
  +    JsonDoc = ?l2b(?JSON_ENCODE(couch_doc:to_json_obj(Doc,[revs,attachments]))),
  +    receive {MiddleMan, next_doc} -> MiddleMan ! {ok, JsonDoc} end,
  +    encoding_worker(Rest).
  +
  +% needed because upload_docs is inside a gen_server so it can't have a mailbox
  +middle_man(EncodingWorker) ->
  +    receive {Uploader, next_doc} ->
  +        receive
  +        {ok, JsonDoc} ->
  +            EncodingWorker ! {self(), next_doc},
  +            Uploader ! {ok, JsonDoc},
  +            middle_man(EncodingWorker);
  +        eof ->
  +            Uploader ! eof,
  +            ok
  +        after 5000 ->
  +            Uploader ! timeout,
  +            middle_man(EncodingWorker)
  +        end
  +    end.
  +
  +request_loop(Ref, Request, Acc) ->
  +    receive
  +    {'DOWN', Ref, _, _, normal} ->
  +        lists:flatten(lists:reverse(Acc));
  +    {'DOWN', Ref, _, _, Reason} ->
  +        exit(Reason)
  +    after 0 ->
  +        ErrorsJson = couch_rep_httpc:request(Request),
  +        request_loop(Ref, Request, [ErrorsJson|Acc])
  +    end.
  +
   writer_loop(Parent, Reader, Target) ->
       case couch_rep_reader:next(Reader) of
       {complete, FinalSeq} ->
  
positive.code:         ok;
      {HighSeq, Docs} ->
          DocCount = length(Docs),
          try write_docs(Target, Docs, []) of
          {ok, []} ->
              Parent ! {update_stats, docs_written, DocCount};
          {ok, Errors} ->
  
negative.code:             Reason = proplists:get_value(<<"reason">>, Props),
              {{Id, Rev}, {ErrId, Reason}}
          end, ErrorsJson),
      {ok, ErrorsList};
  write_docs(Db, Docs) ->
      couch_db:update_docs(Db, Docs, [], replicated_changes).
  