anchor.diff:  %%          {stop, Reason, NewStateData}
   %% --------------------------------------------------------------------
   
  -handle_event({button, '>', ReplyTo}, empty, State0) ->
  +handle_event({"button", ">", ReplyTo}, empty, State0) ->
       State1 = fetch(none,none, State0#state{tailMode=false}),
  -    {next_state, filling, State1#state{stack={button,'>',ReplyTo}}};
  -handle_event({button, '>', ReplyTo}, SN, State0) ->
  +    ?Log("empty stack ~p~n", [">"]),
  +    {next_state, filling, State1#state{stack={"button",">",ReplyTo}}};
  +handle_event({"button", ">", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       {next_state, SN, serve_fwd(SN, State1)};
  -handle_event({button, '>>', ReplyTo}, SN, State0) ->
  +handle_event({"button", ">>", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       {next_state, SN, serve_ffwd(SN, State1)};
  -handle_event({button, '|<', ReplyTo}, SN, State0) ->
  +handle_event({"button", "|<", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       {next_state, SN, serve_top(SN, State1)};
  -handle_event({button, '<', ReplyTo}, SN, State0) ->
  +handle_event({"button", "<", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       {next_state, SN, serve_bwd(SN, State1)};
  -handle_event({button, '<<', ReplyTo}, SN, State0) ->
  +handle_event({"button", "<<", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       {next_state, SN, serve_fbwd(SN, State1)};
  -handle_event({button, Target, ReplyTo}, SN, State0) when is_integer(Target) ->
  +handle_event({"button", Target, ReplyTo}, SN, State0) when is_integer(Target) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       {next_state, SN, serve_target(SN, Target, State1)};
   handle_event({update, ChangeList, ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       State2 = data_update(SN, ChangeList, State1),
       {next_state, SN, State2};
  -handle_event({button, commit, ReplyTo}, SN, State0) ->
  +handle_event({"button", "commit", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       State2 = data_commit(SN, State1),
       {next_state, SN, State2};
  -handle_event({button, rollback, ReplyTo}, SN, State0) ->
  +handle_event({"button", "rollback", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       State2 = data_rollback(SN, State1),
       {next_state, SN, State2};
  -handle_event({button, close, ReplyTo}, SN, #state{dirtyCnt=DC}=State0) when DC==0 ->
  +handle_event({"filter", FilterSpec, ReplyTo}, SN, State0) ->
  +    State1 = reply_stack(SN, ReplyTo, State0),
  +    State2 = data_filter(SN, FilterSpec, State1),
  +    {next_state, SN, State2};
  +handle_event({"sort", SortSpec, ReplyTo}, SN, State0) ->
  +    State1 = reply_stack(SN, ReplyTo, State0),
  +    State2 = data_sort(SN, SortSpec, State1),
  +    {next_state, SN, State2};
  +handle_event({"button", "close", ReplyTo}, SN, #state{dirtyCnt=DC}=State0) when DC==0 ->
       State1 = reply_stack(SN, ReplyTo, State0),
       State2 = fetch_close(State1),
       State3 = gui_close(#gres{state=SN},State2),
       {stop, normal, State3};
  -handle_event({button, close, ReplyTo}, SN, State0) ->
  +handle_event({"button", "close", ReplyTo}, SN, State0) ->
       State1 = reply_stack(SN, ReplyTo, State0),
       State2 = gui_nop(#gres{state=SN,beep=true,message=?MustCommit},State1),
       {next_state, SN, State2}.
  
positive.code:     [gui_row_expand(hd(ets:lookup(TableId, Id)), TableId, RowFun) || Id <- Ids].
  
  keys_before(_, 0, _) -> [];
  keys_before(Key, Limit, #state{nav=ind,indexId=IndexId}) ->
      case ets:select_reverse(IndexId,[{'$1',[{'<',{element,1,'$1'},{const,Key}}],[{element,1,'$1'}]}],Limit) of
          {Keys, _Cont} ->    lists:reverse(Keys);  
  
negative.code:     State2 = data_append(completed,{Recs,true},State1),
      {next_state, completed, State2#state{pfc=0}};
  autofilling({rows, {Recs,true}}, State0) ->
      % revceive and store last input from DB, switch state .. tail mode
      State1= data_append(tailing,{Recs,true},State0),
      {next_state, tailing, State1#state{pfc=0}};
  autofilling(Other, State) ->
      ?Log("autofilling -- unexpected event ~p~n", [Other]),
      {next_state, autofilling, State}.
  
  tailing({"button", "...", ReplyTo}, #state{dirtyCnt=DC}=State0) when DC==0->
      % clear buffer and resume tailing
      State1 = reply_stack(tailing, ReplyTo, State0),
      State2 = data_clear(State1),
      State3 = gui_clear(#gres{state=tailing, loop=">|..."},State2),
      {next_state, tailing, State3};
  tailing({"button", "...", ReplyTo}, State0) ->
      % reject because of uncommitted changes
      State1 = gui_nop(#gres{state=tailing,beep=true,message=?MustCommit},State0#state{replyTo=ReplyTo}),
      {next_state, tailing, State1};
  tailing({"button", ">|...", ReplyTo}, State0) ->
      % resume tailing
      State1 = reply_stack(tailing, ReplyTo, State0),
      State2 = serve_bot(tailing, ">|...", State1),
      {next_state, tailing, State2};
  tailing({"button", ">|", ReplyTo}, #state{bufCnt=0}=State0) ->
      % no data, must ignore
      State1 = gui_nop(#gres{state=tailing,beep=true},State0#state{replyTo=ReplyTo}),
      {next_state, tailing, State1};
  tailing({"button", ">|", ReplyTo}, State0) ->
      % show bottom
      State1 = reply_stack(tailing, ReplyTo, State0),
      State2 = serve_bot(tailing, undefined, State1),
  