anchor.diff:  open_doc_revs(Db, DocId, Revs, Options) ->
       couch_db:open_doc_revs(Db, DocId, Revs, Options).
   
  +%% @spec should_flush() -> true | false
  +%% @doc Calculates whether it's time to flush the document buffer. Considers
  +%%        - memory utilization
  +%%        - number of pending document writes
  +%%        - approximate number of pending attachment writes
  +should_flush(DocCount) when DocCount > ?BUFFER_NDOCS ->
  +    true;
  +should_flush(_DocCount) ->
  +    MeAndMyLinks = [self()|element(2,process_info(self(),links))],
  +    
  +    case length(MeAndMyLinks)/2 > ?BUFFER_NATTACHMENTS of
  +    true -> true;
  +    false ->
  +        case memory_footprint(MeAndMyLinks) > 2*?BUFFER_MEMORY of
  +        true ->
  +            [garbage_collect(Pid) || Pid <- MeAndMyLinks],
  +            memory_footprint(MeAndMyLinks) > ?BUFFER_MEMORY;
  +        false -> false
  +        end
  +    end.
  +
  +%% @spec memory_footprint([pid()]) -> integer()
  +%% @doc Sum of process and binary memory utilization for all processes in list
  +memory_footprint(PidList) ->
  +    ProcessMemory = lists:foldl(fun(Pid, Acc) ->
  +        Acc + element(2,process_info(Pid, memory))
  +    end, 0, PidList),
  +    
  +    BinaryMemory = lists:foldl(fun(Pid, Acc) ->
  +        Acc + binary_memory(Pid)
  +    end, 0, PidList),
  +    
  +    ?LOG_DEBUG("ProcessMem ~p BinaryMem ~p", [ProcessMemory, BinaryMemory]),
  +    ProcessMemory + BinaryMemory.
  +
  +%% @spec binary_memory(pid()) -> integer()
  +%% @doc Memory utilization of all binaries referenced by this process.
  +binary_memory(Pid) ->
  +    lists:foldl(fun({_Id, Size, _NRefs}, Acc) -> Size+Acc end,
  +        0, element(2,process_info(Pid, binary))).
   
   update_doc(#http_db{uri=DbUrl, headers=Headers}, #doc{id=DocId}=Doc, Options) ->
       [] = Options,
  
positive.code:     ets:update_counter(Stats, docs_read, length(Docs)),
      
      %% save them (maybe in a buffer)
      {NewBuffer, NewContext} = case couch_util:should_flush() of
          true ->
              Docs2 = lists:flatten([Docs|Buffer]),
              {ok, Errors} = update_docs(Target, Docs2, [], replicated_changes),
  
negative.code:                     receive
                          {From, continue} -> 
                              %% normal case
                              attachment_loop(ReqId, Conn);
                          {From, fail} ->
                              %% error, failure code
                              ?LOG_ERROR(
                                  "streaming attachment failed with status ~p",
                                  [Status]),
                              catch ibrowse:stop_worker_process(Conn),
                              exit(attachment_request_failed);
                          {From, stop_ok} ->
                              %% stop looping, controller will start a new loop
                              catch ibrowse:stop_worker_process(Conn),
                              stop_ok
                      end
              end,
              attachment_loop(ReqId, Conn);
          {ibrowse_async_response, ReqId, {chunk_start,_}} ->
              attachment_loop(ReqId, Conn);
          {ibrowse_async_response, ReqId, chunk_end} ->
              attachment_loop(ReqId, Conn);
          {ibrowse_async_response, ReqId, {error, Err}} ->
              ?LOG_ERROR("streaming attachment failed with ~p", [Err]),
              catch ibrowse:stop_worker_process(Conn),
              exit(attachment_request_failed);
          {ibrowse_async_response, ReqId, Data} -> 
              receive {From, gimme_data} -> From ! {self(), Data} end,
              attachment_loop(ReqId, Conn);
          {ibrowse_async_response_end, ReqId} ->
              catch ibrowse:stop_worker_process(Conn),
              exit(normal)
      end.
  
  attachment_stub_converter(DbS, Id, Rev, {Name, {stub, Type, Length}}) ->
      #http_db{uri=DbUrl, headers=Headers} = DbS,
      {Pos, [RevId|_]} = Rev,
      Url = lists:flatten([DbUrl, url_encode(Id), "/", url_encode(?b2l(Name)),
          "?rev=", ?b2l(couch_doc:rev_to_str({Pos,RevId}))]),
      ?LOG_DEBUG("Attachment URL ~p", [Url]),
      {ok, RcvFun} = make_attachment_stub_receiver(Url, Headers, Name, 
          Type, Length),
  