anchor.diff:  save_pstate(Key, PState, State) ->
     ?PDB:set(tablename(State), {Key, PState}).
   
  +-spec get_new_id(any(), #pstate{}) -> {cmd_id(), #pstate{}}.
  +get_new_id(Key, PState) ->
  +  Cid = ?get(cid, PState) + 1,
  +  NP1 = ?set(cid, Cid, PState),
  +  Rid = get_replica_id(Key),
  +  {{Rid, Cid}, NP1}.
  +
  +-spec new_replies() -> #replies{}.
  +new_replies() -> #replies{}.
  +
  +%% generic record access
   -spec union_buffer(non_neg_integer(), buffer(), tuple()) -> tuple().
   union_buffer(BufIdx, BufferToMerge, PState) ->
     NewBuf = union(BufferToMerge, element(BufIdx, PState)),
     setelement(BufIdx, PState, NewBuf).
   
  --spec add_to_list(non_neg_integer(), buffer(), tuple()) -> tuple().
  -add_to_list(BufIdx, NewBuffer, PState) ->
  -  NewBuf = [NewBuffer | element(BufIdx, PState)],
  +-spec add_to_list(non_neg_integer(), any(), tuple()) -> tuple().
  +add_to_list(BufIdx, NewListEle, PState) ->
  +  NewBuf = [NewListEle | element(BufIdx, PState)],
     setelement(BufIdx, PState, NewBuf).
   
  --spec add_to_buffer(non_neg_integer(), {any(), comm:mypid()}, crdt:update_fun(), tuple()) -> tuple().
  -add_to_buffer(BufIdx, Client, Fun, PState) ->
  -  BufEle = {Client, Fun},
  -  NewBuf = add(BufEle, element(BufIdx, PState)),
  +-spec add_to_buffer(non_neg_integer(), cmd(), tuple()) -> tuple().
  +add_to_buffer(BufIdx, Cmd, PState) ->
  +  NewBuf = add(Cmd, element(BufIdx, PState)),
     setelement(BufIdx, PState, NewBuf).
   
   -spec get_field(non_neg_integer(), tuple()) -> any().
  
positive.code:   NewLearned = subtract(LearnedVal, CrdtAppliedSet),
    LearnedAsList = sets:to_list(NewLearned),
    NCrdt = lists:foldl(
                  fun({_Client, Fun}, Acc) ->
                    case Fun of
                      {qfun, _} -> Acc;
                      Fun -> apply_updates(DataType, Fun, ReplicaId, Acc)
                    end
                  end, Crdt, LearnedAsList),
    NP5 = ?set(crdt, NCrdt, NP4),
    NP6 = ?set(cmd_set, union(NewLearned, CrdtAppliedSet), NP5),
  
    %% notify all clients of learned commands and apply queries
    [
      begin
        ?TRACE("~p Responding to request ~p", [Key, R]),
        case Fun of
          {qfun, F} ->
            Result = apply_queries(DataType, F, NCrdt),
            comm:send(Client, {read_result, ReqId, Result});
          _ ->
            comm:send(Client, {write_result, ReqId, ok})
        end
      end
    || R = {{ReqId, Client}, Fun} <- LearnedAsList],
  
  
    comm:send_local(self(), {zheng_acceptor, agree, Key, DataType}),
    save_pstate(Key, NP6, State),
  
    %% must be executed immediately, so that sequence number is not missed
    %% at prop_wait, but we cannot use gen_component:post_op(?)
    on({zheng_acceptor, prop_wait, Key}, State), 
    ?TRACE("~p RESPOND DONE seq number ~p", [Key, ?get(seq, NP6) - 1]),
    NP6.
  
  apply_updates(DataType, Funs, ReplicaId, Crdt) when is_list(Funs) ->
    lists:foldl(
      fun(UpdateFun, Acc) ->
        DataType:apply_update(UpdateFun, ReplicaId, Acc)
      end, Crdt, lists:flatten(Funs));
  apply_updates(DataType, Fun, ReplicaId, Crdt) ->
    DataType:apply_update(Fun, ReplicaId, Crdt).
  
  -spec apply_queries(crdt:crdt_module(), [crdt:query_fun()] | crdt:query_fun(), crdt:crdt()) -> any() | [any()].
  apply_queries(DataType, QueryFun, Crdt) when is_function(QueryFun) ->
      DataType:apply_query(QueryFun, Crdt);
  apply_queries(DataType, QueryFuns, Crdt) ->
     [apply_queries(DataType, Fun, Crdt) || Fun <- QueryFuns].
  
  send_to_all_replicas(Key, Message, ConsLookupField, KeyFieldReplace) ->
    Dest = pid_groups:find_a(routing_table),
    [
  
negative.code: set_field(FieldIdx, PState, NewValue) ->
    setelement(FieldIdx, PState, NewValue).
  
  %% more specialized acess
  add_to_notify(Client, Cmd, PState) ->
    NotifyCmd = to_notify_cmd(Client, Cmd),
    ToNotifyList = ?get(to_notify_pending, PState),
    ?set(to_notify_pending, [NotifyCmd | ToNotifyList], PState).
  
  set_to_notify_after_cmd_learned(NotifyList, WaitForCmd, PState) ->
    ListenDict = ?get(wait_for_learned, PState),
    CmdId = get_cmd_id(WaitForCmd),
    ?set(wait_for_learned, dict:store(CmdId, NotifyList, ListenDict), PState).
  
  %%%%%%%%%%%%%%%%%%%%%
  %% Command and Command set managment
  %%%%%%%%%%%%%%%%%%%%%
  -spec new_client(any(), any()) -> client().
  new_client(ReqId, Client) -> {ReqId, Client}.
  
  -spec new_update_cmd(cmd_id(), crdt:update_fun()) -> cmd().
  new_update_cmd(Id, Fun) -> {Id, Fun}.
  
  -spec new_query_cmd(cmd_id(), crdt:query_fun()) -> cmd().
  new_query_cmd(Id, Fun) -> {Id, {qfun, Fun}}.
  
  -spec new_noop(cmd_id()) -> cmd().
  new_noop(Id) -> {Id, noop}.
  
  %% Notification commands are used only for client notification
  %% We do not need to store the update function as the resutl is always ok.
  %% Query functions are applied upon learning. We do not need old ID because
  %% they are never merged with other buffers.
  -spec to_notify_cmd(client(), cmd()) -> notify_cmd().
  to_notify_cmd(Client, Cmd = {_ID, Fun}) ->
    case is_query(Cmd) of
      true ->
        {Client, Fun};
      false ->
        {Client, notify_ok}
    end.
  
  -spec get_cmd_id(cmd()) -> cmd_id().
  get_cmd_id({Id, _}) -> Id.
  
  -spec get_cmd_fun(cmd()) -> any().
  get_cmd_fun({_Id, Fun}) -> Fun.
  
  -spec is_noop(cmd()) -> boolean().
  is_noop({_Id, noop}) -> true;
  is_noop(_) -> false.
  
  -spec is_query(cmd()) -> boolean().
  is_query({_Id, {qfun, _Fun}}) -> true;
  is_query(_) -> false.
  
  -spec is_update(cmd()) -> boolean().
  is_update(Cmd) -> not is_query(Cmd).
  
  -spec add(cmd(), buffer()) -> buffer().
  add(Element, Buff) -> sets:add_element(Element, Buff).
  
  -spec subtract(buffer(), buffer()) -> buffer().
  