anchor.diff:      recv -> N+1;
       _    -> N
     end.
  +
  +spawn_printer(PrintFun, Cnf) ->
  +  Cnf#cnf{print_pid=spawn_link(fun() -> print_init(PrintFun) end)}.
   
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% the default print fun for blocking mode (i.e. return a term).
  
positive.code: improper_map(F, [A|B]) when not is_list(B) -> [F(A)|F(B)];
  improper_map(F, [A|B]) -> [F(A)|improper_map(F, B)].
  
  mk_out(#cnf{print_re=RE, print_file=File}) ->
    FD = get_fd(File),
    fun(F, A) ->
        Str=flat(F, A),
        case RE =:= "" orelse re:run(Str, RE) =/= nomatch of
          true  -> io:fwrite(FD, "~s~n", [Str]);
          false -> ok
        end
    end.
  
  get_fd(FD) when is_atom(FD); is_pid(FD) ->
    FD;
  get_fd("") ->
    standard_io;
  get_fd(FN) ->
    case file:open(FN, [write]) of
      {ok, FD} -> FD;
      _ -> throw({cannot_open, FN})
    end.
  
  fix_ts(MS, TS) ->
  
negative.code: 
  mk_outer(#cnf{file=[_|_]}) ->
    fun(_) -> ok end;
  mk_outer(#cnf{print_depth=Depth, print_msec=MS, print_return=Ret, print_calls=Calls} = Cnf) ->
    OutFun = mk_out(Cnf),
    fun({Tag, Data, PI, TS}) -> outer(Tag, Data, PI, TS, Depth, MS, Ret, Calls, OutFun) end.
  
  outer(Tag, Data, PI, TS, Depth, MS, Ret, Calls, OutFun) ->
    MTS = fix_ts(MS, TS),
    case {Tag, Data} of
      {'meta', {recs, Recs}} ->
        put_recs(Recs);
      {'meta', _} ->
        ok;
      {'call_time', {_, false}} ->
        ok;
      {'call_time', {{M, F, A}, PerProcCT}} ->
        {Count, Time} = lists:foldl(fun per_proc/2, {0, 0}, PerProcCT),
        [OutFun("% ~6s : ~6s : ~6s : ~w:~w/~w",
                [human(Count), human(Time), human(Time/Count), M, F, A]) || 0 < Count];
      {'call_count', {_, false}} ->
        ok;
      {'call_count', {{M, F, A}, Count}} ->
        [OutFun("~n% ~6s : ~w:~w/~w", [human(Count), M, F, A]) || 0 < Count];
      {'call', {{M, F, A}, Bin}} ->
        case Calls of
          true ->
            case is_integer(A) of
              true ->
                OutFun("~n% ~s ~s~n% ~w:~w/~w", [MTS, to_str(PI), M, F, A]);
              false->
                Args = [flat("~P", [expand(A0), Depth]) || A0 <- A],
                AL = string:join(Args, ", "),
                OutFun("~n% ~s ~s~n% ~w:~w(~s)", [MTS, to_str(PI), M, F, AL])
            end,
            lists:foreach(fun(L) -> OutFun("%   ~s", [L]) end, stak(Bin));
          false->
            ok
        end;
      {'retn', {{M, F, A}, Val0}} ->
        Val = case Ret of
                true  -> expand(Val0);
                false -> '...'
              end,
        OutFun("~n% ~s ~s~n% ~p:~p/~p -> ~P",
               [MTS, to_str(PI), M, F, A, Val, Depth]);
      {'send', {MSG, ToPI}} ->
        OutFun("~n% ~s ~s~n% ~s <<< ~P",
               [MTS, to_str(PI), to_str(ToPI), expand(MSG), Depth]);
      {'recv', MSG} ->
        OutFun("~n% ~s ~s~n% <<< ~P",
               [MTS, to_str(PI), expand(MSG), Depth])
    end.
  
  per_proc({_, Count, Sec, Usec}, {AC, AT}) ->
    {Count+AC, Sec*1000000+Usec+AT}.
  
  to_str({Pid, Reg}) ->
    flat("~w(~p)", [Pid, Reg]);
  