anchor.diff:      DocEdited = Doc#doc{
           atts = NewAtt ++ [A || A <- Atts, A#att.name /= FileName]
       },
  -    {ok, UpdatedRev} = couch_db:update_doc(Db, DocEdited, []),
  -    #db{name=DbName} = Db,
  -
  -    {Status, Headers} = case Method of
  -        'DELETE' ->
  -            {200, []};
  -        _ ->
  -            {201, [{"ETag", "\"" ++ ?b2l(couch_doc:rev_to_str(UpdatedRev)) ++ "\""},
  -               {"Location", absolute_uri(Req, "/" ++
  -                binary_to_list(DbName) ++ "/" ++
  -                binary_to_list(DocId) ++ "/" ++
  -                binary_to_list(FileName)
  -            )}]}
  -        end,
  -    send_json(Req,Status, Headers, {[
  -        {ok, true},
  -        {id, DocId},
  -        {rev, couch_doc:rev_to_str(UpdatedRev)}
  -    ]});
  +
  +    Headers = case Method of
  +    'DELETE' ->
  +        [];
  +    _ ->
  +        [{"Location", absolute_uri(Req, "/" ++
  +            ?b2l(Db#db.name) ++ "/" ++
  +            ?b2l(DocId) ++ "/" ++
  +            ?b2l(FileName)
  +        )}]
  +    end,
  +    update_doc(Req, Db, DocId, DocEdited, Headers);
   
   db_attachment_req(Req, _Db, _DocId, _FileNameParts) ->
       send_method_not_allowed(Req, "DELETE,GET,HEAD,PUT").
  
positive.code:     NewDoc = Doc#doc{
          atts = UpdatedAtts ++ OldAtts2
      },
      {ok, NewRev} = couch_db:update_doc(Db, NewDoc, []),
  
      send_json(Req, 201, [{"ETag", "\"" ++ ?b2l(couch_doc:rev_to_str(NewRev)) ++ "\""}], {[
          {ok, true},
          {id, DocId},
          {rev, couch_doc:rev_to_str(NewRev)}
      ]});
  
  db_doc_req(#httpd{method='PUT'}=Req, Db, DocId) ->
      #doc_query_args{
          update_type = UpdateType
      } = parse_doc_query(Req),
      couch_doc:validate_docid(DocId),
      
      Loc = absolute_uri(Req, "/" ++ ?b2l(Db#db.name) ++ "/" ++ ?b2l(DocId)),
      RespHeaders = [{"Location", Loc}],
      case couch_util:to_list(couch_httpd:header_value(Req, "Content-Type")) of
      ("multipart/related;" ++ _) = ContentType ->
          {ok, Doc0, WaitFun, Parser} = couch_doc:doc_from_multi_part_stream(
              ContentType, fun() -> receive_request_data(Req) end),
          Doc = couch_doc_from_req(Req, DocId, Doc0),
          try
              Result = update_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType),
              WaitFun(),
              Result
          catch throw:Err ->
  
negative.code:     _ ->
          Options = []
      end,
      case couch_httpd:qs_value(Req, "batch") of
      "ok" ->
          % async batching
          spawn(fun() ->
                  case catch(couch_db:update_doc(Db, Doc, Options, UpdateType)) of
                  {ok, _} -> ok;
                  Error ->
                      ?LOG_INFO("Batch doc error (~s): ~p",[DocId, Error])
                  end
              end),
          send_json(Req, 202, Headers, {[
              {ok, true},
              {id, DocId}
          ]});
      _Normal ->
          % normal
          {ok, NewRev} = couch_db:update_doc(Db, Doc, Options, UpdateType),
          NewRevStr = couch_doc:rev_to_str(NewRev),
          ResponseHeaders = [{"ETag", <<"\"", NewRevStr/binary, "\"">>}] ++ Headers,
          send_json(Req,
              if Deleted orelse Req#httpd.method == 'DELETE' -> 200;
              true -> 201 end,
              ResponseHeaders, {[
                  {ok, true},
                  {id, DocId},
                  {rev, NewRevStr}]})
      end.
  
  couch_doc_from_req(Req, DocId, #doc{revs=Revs}=Doc) ->
      validate_attachment_names(Doc),
  