anchor.diff:  
   
   %% @private
  --spec del_all(nksip:app_id(), nksip:aor(), nksip:request()) ->
  -    ok | not_found | no_return().
  -
  -del_all(AppId, AOR, #sipmsg{call_id=CallId, cseq=CSeq}) ->
  +-spec del_all(nksip:request()) ->
  +    ok | not_found.
  +
  +del_all(Req) ->
  +    #sipmsg{
  +        app_id = AppId,
  +        to = #uri{scheme=Scheme, user=ToUser, domain=ToDomain},
  +        call_id = CallId, 
  +        cseq = CSeq
  +    } = Req,
  +    AOR = {Scheme, ToUser, ToDomain},
       {ok, RegContacts} = callback_get(AppId, AOR),
       lists:foreach(
           fun(#reg_contact{call_id=CCallId, cseq=CCSeq}) ->
  
positive.code: -spec request(nksip:request()) ->
      nksip:sipreply().
  
  request(Request) ->
      try
          process(Request)
      catch
          throw:Throw -> Throw
      end.
  
negative.code: 
  
  %% @private
  -spec check_outbound(nksip:request()) ->
      {true|false|undefined, nksip:request()}.
  
  check_outbound(Req) ->
      #sipmsg{app_id=AppId, vias=Vias, transport=Transp} = Req,
      case nksip_sipmsg:supported(Req, <<"outbound">>) of
          true when length(Vias) > 1 ->  % We are not the first host
              ObProc = case nksip_sipmsg:headers(Req, <<"Path">>, uris) of
                  [#uri{opts=PathOpts}] -> lists:member(<<"ob">>, PathOpts);
                  _ -> false
              end,
              {ObProc, Req};
          true ->
              {ok, _, AppOpts, _} = nksip_sipapp_srv:get_opts(AppId),
              #transport{proto=Proto, listen_ip=Ip, listen_port=Port} = Transp,
              Host = nksip_transport:get_listenhost(Ip, AppOpts),
              case nksip_transport:get_connected(AppId, Proto, Ip, Port) of
                  [{_, Pid}|_] ->
                      Flow = base64:encode(term_to_binary(Pid)),
                      Path = nksip_transport:make_route(sip, Proto, Host, Port, 
                                                        <<"NkF", Flow/binary>>, 
                                                        [<<"lr">>]),
                      Headers1 = nksip_headers:update(Req, 
                          [{add_before_single, <<"Path">>, Path}]),
                      Req1 = Req#sipmsg{headers=Headers1},
                      {true, Req1};
                  [] ->
                      {false, Req}
              end;
          false ->
              {unsupported, Req}
      end.
  
  
  %% @private
  -spec process(nksip:request(), true|false|unsupported) ->
      ok.
  
  process(Req, ObProc) ->
      #sipmsg{
          to = #uri{scheme=Scheme},
          contacts = Contacts
      } = Req,
      if
          Scheme==sip; Scheme==sips -> ok;
          true -> throw(unsupported_uri_scheme)
      end,
      Default = case nksip_sipmsg:field(Req, expires) of
          Default0 when is_integer(Default0) -> Default0;
          _ -> nksip_config:get(registrar_default_time)
      end,
      Times = {
          nksip_config:get(registrar_min_time), 
          nksip_config:get(registrar_max_time),
          Default,
          nksip_lib:timestamp()
      },
      case Contacts of
          [] -> ok;
          [#uri{domain=(<<"*">>)}] when Default==0 -> del_all(Req);
          _ -> update(Req, Times, ObProc)
      end.
  
  
  %% @private
  -spec update(nksip:request(), {integer(), integer(), integer(), integer()}, 
               true|false|unsupported) ->
      ok.
  
  update(Req, Times, ObProc) ->
      #sipmsg{
          app_id = AppId, 
          to = #uri{scheme=Scheme, user=ToUser, domain=ToDomain},
          contacts = Contacts,
          call_id = CallId, 
          cseq = CSeq,
          transport = Transp
      } = Req,
      Path = case nksip_sipmsg:header(Req, <<"Path">>, uris) of
          error -> throw(invalid_request);
          Path0 -> Path0
      end,
      Base = #reg_contact{
          call_id = CallId, 
          cseq = CSeq,
          transport = Transp,
          path = Path
      },
      RegContacts = gen_regcontacts(Contacts, Base, Times, ObProc, []),
      % Check no several reg-id allowed
      case [true || #reg_contact{index={ob, _, _}, expire=Exp} <- RegContacts, Exp>0] of
          [_, _|_] -> throw(invalid_request);
          _ -> ok
      end,
      AOR = {Scheme, ToUser, ToDomain},
      {ok, Regs} = callback_get(AppId, AOR),
      {_, _, _, Now} = Times,
      Contacts1 = [
          RegContact ||
          #reg_contact{expire=Exp} = RegContact <- Regs, 
          Exp > Now
      ],
      case update_regcontacts(RegContacts, Contacts1) of
          [] -> 
              case callback(AppId, {del, AOR}) of
                  ok -> ok;
                  not_found -> ok;
                  _ -> throw({internal, "Error calling registrar 'del' callback"})
              end;
          Contacts2 -> 
              GlobalExpire = lists:max([Exp-Now||#reg_contact{expire=Exp} <- Contacts2]),
              % Set a minimum expiration check of 5 secs
              case callback(AppId, {put, AOR, Contacts2, max(GlobalExpire, 5)}) of
                  ok -> ok;
                  _ -> throw({internal, "Error calling registrar 'put' callback"})
              end
  