anchor.diff:  
   -define(BUCKET, <<"b">>).
   -define(KEY, <<"k">>).
  --define(NUMTESTS, 1000).
  +-define(NUMTESTS, 500).
   -define(QC_OUT(P),
           eqc:on_output(fun(Str, Args) ->
                                 io:format(user, Str, Args) end, P)).
   
   %%====================================================================
  +%% eunit test
  +%%====================================================================
  +
  +counter_value_test_() ->
  +    {timeout, 60000, % do not trust the docs - timeout is in msec
  +      ?_assertEqual(true, quickcheck(numtests(?NUMTESTS, ?QC_OUT(prop_value()))))}.
  +
  +counter_merge_test_() ->
  +    {timeout, 60000, % do not trust the docs - timeout is in msec
  +       ?_assertEqual(true, quickcheck(numtests(?NUMTESTS, ?QC_OUT(prop_merge()))))}.
  +
  +counter_update_test_() ->
  +    {timeout, 60000, % do not trust the docs - timeout is in msec
  +       ?_assertEqual(true, quickcheck(numtests(?NUMTESTS, ?QC_OUT(prop_update()))))}.
  +
  +%%====================================================================
   %% Shell helpers
   %%====================================================================
   
  
positive.code: test_update(N) ->
      quickcheck(numtests(N, prop_update())).
  
  prop_value() ->
      %% given any riak_object,
      %% value will return the value
      %% of merged PN-Counter payloads (zero if no counters)
      ?FORALL(RObj, riak_object(),
              collect(num_counters(RObj),
                      equals(sumthem(RObj), riak_kv_counter:value(RObj)))).
  
  prop_merge() ->
      %% given any riak_object
      %% merge will return a
      %% riak_object where all counter siblings
      %% are squashed to a single value
      %% and all counter metadata is squashed to
      %% a single dict of indexes
      %% all other siblings must be maintained, untouched.
      ?FORALL({RObj, IndexSpecs}, {riak_object(), index_specs()},
              begin
                  Merged = riak_kv_counter:merge(RObj, IndexSpecs),
                  NumGeneratedCounters = num_counters(RObj),
                  NumMergedCounters =  num_counters(Merged),
                  ExpectedCounters = case NumGeneratedCounters of
                                         0 -> 0;
                                         _ -> 1
                                     end,
                  %% Check that the structure of the merged counter is correct
                  ExpectedCounter = merge_object(RObj, undefined),
                  {MergedMeta, MergedCounter} = single_counter(Merged),
                  %% Check that the meta is correct
                  ExpectedIndexMeta = expected_indexes(IndexSpecs, NumGeneratedCounters),
                  %% Check that non-sibling values and meta are untouched
                  ExpectedSiblings = non_counter_siblings(RObj),
                  ActualSiblings = non_counter_siblings(Merged),
                  ?WHENFAIL(
                     begin
                         io:format("Gen ~p\n", [RObj]),
                         io:format("Merged ~p\n", [Merged]),
                         io:format("Index Specs ~p~n", [IndexSpecs])
                     end,
                     collect(NumGeneratedCounters,
                             conjunction([
                                          {value, equals(sumthem(RObj), riak_kv_counter:value(Merged))},
                                          {number_of_counters,
                                           equals(ExpectedCounters, NumMergedCounters)},
                                         {counter_structure,
                                          counters_equal(ExpectedCounter, MergedCounter)},
                                          {siblings, equals(lists:sort(ExpectedSiblings), lists:sort(ActualSiblings))},
                                          {index_meta, equals(ExpectedIndexMeta, sorted_index_meta(MergedMeta))}
                                         ])))
              end).
  
  prop_update() ->
      %% given any riak object, will update the counter value of that object.
      %% If any counter values are present they will be merged and incremented
      %% if not, then a new counter is created, and incremented
      %% all non-counter values and meta are left alone
      %% only counter index meta is preserved, again using indexspecs.
      ?FORALL({RObj, IndexSpecs, Actor, Amt},
              {riak_object(), index_specs(), noshrink(binary(4)), int()},
              begin
                  Updated = riak_kv_counter:update(RObj, IndexSpecs, Actor, Amt),
  
                  NumMergedCounters =  num_counters(Updated),
                  ExpectedCounters = case {NumMergedCounters, Amt} of
                                         {0, 0} -> 0;
                                         _ -> 1
                                     end,
                  %% Check that the structure of the merged counter is correct
                  CounterSeed = case Amt of
                                    0 -> undefined;
                                    _ -> riak_kv_pncounter:new(Actor, Amt)
                                end,
                  ExpectedCounter = merge_object(RObj, CounterSeed),
                  {MergedMeta, MergedCounter} = single_counter(Updated),
                  %% Check that the meta is correct
                  ExpectedIndexMeta = expected_indexes(IndexSpecs, ExpectedCounters),
                  %% Check that non-sibling values and meta are untouched
                  ExpectedSiblings = non_counter_siblings(RObj),
                  ActualSiblings = non_counter_siblings(Updated),
  
                  ?WHENFAIL(
                     begin
                         io:format("Gen ~p~n", [RObj]),
                         io:format("Updated ~p~n", [Updated]),
                         io:format("Index Specs ~p~n", [IndexSpecs]),
                         io:format("Amt ~p~n", [Amt]),
                         io:format("Merged counter ~p Expected counter ~p", [ExpectedCounter, MergedCounter])
                     end,
                     collect(Amt,
                             conjunction([
                                         {counter_value, equals(sumthem(RObj) + Amt,
                                                                riak_kv_counter:value(Updated))},
                                           {number_of_counters,
                                           equals(ExpectedCounters, NumMergedCounters)},
                                         {counter_structure,
                                          counters_equal(ExpectedCounter, MergedCounter)},
                                          {siblings, equals(lists:sort(ExpectedSiblings), lists:sort(ActualSiblings))},
                                          {index_meta, equals(ExpectedIndexMeta, sorted_index_meta(MergedMeta))}
                                         ])
                            ))
              end).
  
  %% Both update and merge
  %% share most of their properties
  %% so reuses them
  verify_merge(Generated, PostAction, IndexSpecs) ->
      NumGeneratedCounters = num_counters(Generated),
      NumPostActionCounters =  num_counters(PostAction),
      ExpectedCounters = case NumGeneratedCounters of
                             0 -> 0;
                             _ -> 1
                         end,
      %% Check that the structure of the merged counter is correct
      ExpectedCounter = merge_object(Generated, undefined),
      {PostActionMeta, PostActionCounter} = single_counter(PostAction),
      %% Check that the meta is correct
      ExpectedIndexMeta = expected_indexes(IndexSpecs, NumGeneratedCounters),
      %% Check that non-sibling values and meta are untouched
      ExpectedSiblings = non_counter_siblings(Generated),
      ActualSiblings = non_counter_siblings(PostAction),
      conjunction([{number_of_counters,
                    equals(ExpectedCounters, NumPostActionCounters)},
                   {counter_structure,
                    counters_equal(ExpectedCounter, PostActionCounter)},
                   {siblings, equals(lists:sort(ExpectedSiblings), lists:sort(ActualSiblings))},
                   {index_meta, equals(ExpectedIndexMeta, sorted_index_meta(PostActionMeta))}
                  ]).
  
  %%====================================================================
  %% Helpers
  %%====================================================================
  sorted_index_meta(undefined) ->
      undefined;
  sorted_index_meta(Meta) ->
  
negative.code: 
  -module(kv_counter_eqc).
  
  -ifdef(EQC).
  -include_lib("eqc/include/eqc.hrl").
  -include_lib("eunit/include/eunit.hrl").
  
  -include("../src/riak_kv_wm_raw.hrl").
  