anchor.diff:  %%%===================================================================
   %%% 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;
  
positive.code:         BucketProps, N
      ).
  
  %% See riak_kv_ensemble_router:random for justification
  random(N) ->
      erlang:phash2(erlang:statistics(io), N) + 1.
  
  
negative.code:             false ->
                  riak_core_apl:get_primary_apl(DocIdx, NVal, riak_kv)
          end,
      case validate_options(NVal, Preflist, Options, BucketProps) of
          {ok, W, PW} ->
              Workers = workers(),
              R = random(size(Workers)),
              Worker = element(R, workers()),
              ReqId = erlang:monitor(process, Worker),
              RObj2 = riak_object:set_vclock(RObj, vclock:fresh(<<0:8>>, 1)),
              RObj3 = riak_object:update_last_modified(RObj2),
              RObj4 = riak_object:apply_updates(RObj3),
              Bucket = riak_object:bucket(RObj4),
              Key = riak_object:key(RObj4),
              EncodedVal = riak_object:to_binary(v1, RObj4),
              gen_server:cast(
                  Worker,
                  {put, Bucket, Key, EncodedVal, ReqId, Preflist,
                      #rec{w=W, pw=PW, n_val=NVal, from=self()}
                  }
              ),
              Timeout = case proplists:get_value(timeout, Options, ?DEFAULT_TIMEOUT) of
                            N when is_integer(N) andalso N > 0 ->
                                N;
                            _ ->
                                ?DEFAULT_TIMEOUT
                        end,
              receive
                  {'DOWN', ReqId, process, _Pid, _Reason} ->
                      {error, riak_kv_fast_put_server_crashed};
                  {ReqId, Response} ->
                      erlang:demonitor(ReqId, [flush]),
                      Response
              after Timeout ->
                  gen_server:cast(Worker, {cancel, ReqId}),
                  receive
                      {ReqId, Response} ->
                          Response
                  end
              end;
          Error ->
              Error
      end.
  
  %%%===================================================================
  