anchor.diff:  %%%  Patt - list(term(P))|term(P) - all terms P must match the message.
   %%%    funs, ports, refs and pids ar turned into atoms.
   %%%  CBs - list(function()) -  CB|list(CB)
  -%%%  CB - fun(F)|atom(M)|{fun(F),term(Init)}|{atom(M),term(Init)}
  +%%%  CB - fun(F)|atom(M)|{fun(F), term(Init)}|{atom(M), term(Init)}
   %%%  M - if M is '', the default callback is called. it will write the
   %%%    trace message to a file (if Init is a string) or the screen.
   %%%    otherwise, M:go(Msg,Seq,State) is called
  
positive.code: is_cb(M) when is_atom(M) -> true = lists:member({go,3},M:module_info(exports));
  is_cb(F) when is_function(F) -> {arity,3} = erlang:fun_info(F,arity).
  
  do(end_of_trace, State) ->
    do_do(end_of_trace, State);
  do(_Mess, #state{max = Max, seq = Seq} = Stat) when Max < Seq ->
    Stat#state{eof=true};
  do(Mess, #state{min = Min, seq = Seq} = Stat) when Seq < Min ->
    case mass(Mess) of
      [] -> Stat;
      _ -> Stat#state{seq = Seq+1}
    end;
  do(Mess, Stat) ->
    case mass(Mess) of
      [] -> Stat;
      Ms -> do_do(Ms, Stat)
    end.
  
  do_do(end_of_trace = Ms, #state{cbs=CBs, seq=Seq} = State) ->
    State#state{cbs=do_safe_cbs(CBs, Ms, Seq, [])};
  do_do(Mess, #state{pattern=Patt, cbs=CBs, seq=Seq} = State) ->
    case grep(Patt, Mess) of
      false -> State#state{seq = Seq+1};
      true ->
        State#state{seq = Seq+1,
                    hits = State#state.hits+1,
                    cbs=do_safe_cbs(CBs, Mess, Seq, [])}
    end.
  
  do_safe_cbs([], _, _, O) -> lists:reverse(O);
  do_safe_cbs([CB|CBs], Msg, Seq, O) ->
    do_safe_cbs(CBs, Msg, Seq, [safe_cb(CB,Msg,Seq)|O]).
  
  safe_cb({{M,F},State},Msg,Seq) -> {{M,F},M:F(Msg,Seq,State)};
  safe_cb({Fun,State},Msg,Seq) -> {Fun,Fun(Msg,Seq,State)}.
  
negative.code:   end.
  
  atomize(FileName) ->
    list_to_atom(hd(lists:reverse(string:tokens(FileName,"/")))).
  
  funi(Fun) ->
    case erlang:fun_info(Fun,module) of
      {_,rpc} ->
        case erlang:fun_info(Fun,env) of
          {_,[_,_,Pid,A,_F,_M]} when is_pid(Pid),is_list(A) ->
            {rpc,{call_dummy,node(Pid)}};
          {_,[_,Pid,A,F,M]} when is_pid(Pid)->
            {rpc,{call,node(Pid)},{M,F,length(A)}};
          {_,[Pid,A,F,M]} when is_pid(Pid),is_list(A) ->
            {rpc,{cast,node(Pid)},{M,F,length(A)}};
          _X ->
            {rpc}
        end;
      {_,Mod} ->
        case erlang:fun_info(Fun,pid) of
          {_,Pid} when is_pid(Pid) -> {'fun',{Mod,node(Pid)}};
          {_,X} -> {'fun',{Mod,X}}
        end
    end.
  
  