anchor.diff:  -type matchspec() :: [{[term()], [term()], [term()]}].
   -type shellfun() :: fun((_) -> term()).
   -type millisecs() :: non_neg_integer().
  +-type pidspec() :: all | existing | new | recon:pid_term().
   -type max_traces() :: non_neg_integer().
   -type max_rate() :: {max_traces(), millisecs()}.
   
                      %% trace options
  --type options() :: [ {pid, all | existing | new | recon:pid_term()} % default: all
  +-type options() :: [ {pid, pidspec() | [pidspec(),...]} % default: all
                      | {timestamp, formatter | trace} % default: formatter
                      | {args, args | arity}           % default: args
                      %% match pattern options
  
positive.code:     trace_calls(MFAs, Pid, Opts).
  
  trace_calls(MFAs, Pid, Opts) ->
      {PidSpec, TraceOpts, MatchOpts} = validate_opts(Opts),
      Matches = [begin
                  {Arity, Spec} = validate_mfa(Mod, Fun, Args),
                  erlang:trace_pattern({Mod, Fun, Arity}, Spec, MatchOpts)
                 end || {Mod, Fun, Args} <- MFAs],
      erlang:trace(PidSpec, true, [call, {tracer, Pid} | TraceOpts]),
      lists:sum(Matches).
  
  validate_opts(Opts) ->
      PidSpec = case proplists:get_value(pid, Opts, all) of
                  all -> all;
                  existing -> existing;
                  new -> new;
                  PidTerm -> recon_lib:term_to_pid(PidTerm)
      end,
      TraceOpts = case proplists:get_value(timestamp, Opts, formatter) of
                      formatter -> [];
                      trace -> [timestamp]
  
negative.code:                     arity -> [arity]
                   end,
      MatchOpts = [proplists:get_value(scope, Opts, global)],
      {PidSpecs, TraceOpts, MatchOpts}.
  
  %% Support the regular specs, but also allow `recon:pid_term()' and lists
  %% of further pid specs.
  -spec validate_pid_specs(pidspec() | [pidspec(),...]) ->
      [all | new | existing | pid(), ...].
  validate_pid_specs(all) -> [all];
  validate_pid_specs(existing) -> [existing];
  validate_pid_specs(new) -> [new];
  validate_pid_specs([Spec]) -> validate_pid_specs(Spec);
  validate_pid_specs(PidTerm = [Spec|Rest]) ->
      %% can be "<a.b.c>" or [pidspec()]
      try
          [recon_lib:term_to_pid(PidTerm)]
      catch
          error:function_clause ->
              validate_pid_specs(Spec) ++ validate_pid_specs(Rest)
      end;
  validate_pid_specs(PidTerm) ->
      %% has to be `recon:pid_term()'.
      [recon_lib:term_to_pid(PidTerm)].
  
  validate_mfa(Mod, Fun, Args) when is_function(Args) ->
      validate_mfa(Mod, Fun, fun_to_ms(Args));
  