anchor.diff:                          {PrimaryOkays + 1, FallbackOkays, Errors};
                       {ok, fallback} ->
                           {PrimaryOkays, FallbackOkays + 1, Errors};
  -                    {{error, Reason}, primary} ->
  -                        {PrimaryOkays, FallbackOkays, [{error, {primary, Reason}} | Errors]};
  -                    {{error, Reason}, fallback} ->
  -                        {PrimaryOkays, FallbackOkays, [{error, {fallback, Reason}} | Errors]}
  +                    {{error, Reason}, _} ->
  +                        {PrimaryOkays, FallbackOkays, [Reason | Errors]}
                   end,
  -            case enough(W, PW, NVal, PrimaryOkays1, FallbackOkays1, Errors1) of
  -                {true, Response} ->
  +            % TODO use riak_kv_put_core here instead
  +            case enough(W, PW, NVal, PrimaryOkays1 + FallbackOkays1, PrimaryOkays1, length(Errors1)) of
  +                true ->
                       {_, NewState} = erase_request_record(ReqId, State),
  -                    reply(From, ReqId, Response);
  -                {false, _} ->
  +                    reply(From, ReqId, response(W, PW, NVal, PrimaryOkays1 + FallbackOkays1, PrimaryOkays1, Errors1, length(Errors)));
  +                false ->
                       NewRec = Rec#rec{
                           primary_okays = PrimaryOkays1,
                           fallback_okays = FallbackOkays1,
  
positive.code:     end.
  
  
  enough(W, PW, NVal, NumPrimaryOkays, NumFallbackOkays, Errors) ->
      case PW of
          Val when is_integer(Val) andalso Val > 0 ->
              enough(PW, NumPrimaryOkays, NVal, Errors);
          _Rubbish ->
              enough(W, NumPrimaryOkays + NumFallbackOkays, NVal, Errors)
      end.
  
  enough(Threshold, Okays, TotalPossible, Errors) ->
      case Threshold =< Okays of
          true -> {true, ok};
          false ->
              NumErrors = length(Errors),
              case (TotalPossible - NumErrors) < Threshold of
                  true -> {true, {error, too_many_fails}};
                  false -> {false, noreply}
              end
      end.
  
  reply(From, ReqId, Term) ->
  
negative.code: %%%===================================================================
  %%% Internal functions
  %%%===================================================================
  
  validate_options(NVal, Preflist, Options, BucketProps) ->
      PW = get_rw_value(pw, BucketProps, NVal, Options),
      W = case get_rw_value(dw, BucketProps, NVal, Options) of
              error   -> get_rw_value(w, BucketProps, NVal, Options);
              DW      -> erlang:max(DW, get_rw_value(w, BucketProps, NVal, Options))
          end,
      NumPrimaries = length([x || {_, primary} <- Preflist]),
      NumVnodes = length(Preflist),
      MinVnodes = lists:max([1, W, PW]),
      if
          PW =:= error ->
              {error, pw_val_violation};
          W =:= error ->
              {error, w_val_violation};
          (W > NVal) or (PW > NVal) ->
              {error, {n_val_violation, NVal}};
          PW > NumPrimaries ->
              {error, {pw_val_unsatisfied, PW, NumPrimaries}};
          NumVnodes < MinVnodes ->
              {error, {insufficient_vnodes, NumVnodes, need, MinVnodes}};
          true ->
              {ok, W, PW}
      end.
  
  send_vnodes([], Proxies, _Bucket, _Key, _EncodedVal, _ReqId) ->
      Proxies;
  