anchor.diff:  %% userdevguide-begin rt_loop:state
   -opaque(state_active() :: {Neighbors    :: nodelist:neighborhood(),
                              RT           :: ?RT:rt(),
  -                           ERT          :: ?RT:external_rt()}).
  +                           ERT          :: ?RT:external_rt(),
  +                           DHTNodePid   :: comm:mypid()}).
   -type(state_inactive() :: {inactive,
                              MessageQueue::msg_queue:msg_queue()}).
   %% -type(state() :: state_active() | state_inactive()).
  
positive.code:     case rt_chord:next_hop(Neighbors, ERT, Key) of
          succ ->
              %% TODO: do I need a WrappedMsg here ??!
              % TODO: check efficients of pid_groups:get_my/1 vs. caching the PID or retrieving from Neighbors - caching is probably the best
              comm:send_local(pid_groups:get_my(dht_node), {lookup_decision, Key, Hops, WrappedMsg});
          NextHop ->
              NewMsg = {?lookup_aux, Key, Hops + 1, WrappedMsg},
              comm:send(NextHop, NewMsg, [{shepherd, self()}])
      end.
  
  -spec lookup_aux_leases(Neighbors::nodelist:neighborhood(), ERT::?RT:external_rt(),
                          Key::intervals:key(), Hops::non_neg_integer(),
                          Msg::comm:message()) -> ok.
  lookup_aux_leases(Neighbors, ERT, Key, Hops, Msg) ->
      %% log:pal("lookup_aux_leases in rt_loop"),
      %% TODO implement WrappedMsg
      WrappedMsg = ?RT:wrap_message(Key, Msg, no_dht_node_state, Hops),
      % NOTE: leases do not require routing through predecessor -> let the own node decide:
      case intervals:in(Key, nodelist:node_range(Neighbors)) of
          true ->
              % TODO: use lookup_fin
              comm:send_local(pid_groups:get_my(dht_node),
                              {?lookup_fin, Key, ?HOPS_TO_DATA(Hops), WrappedMsg});
          false ->
              %% next_hop and nodelist:succ(Neighbors) return different nodes if
              %% key is in the interval of the succ.
  
negative.code:     gen_component:post_op({periodic_rt_rebuild}, State);
  
  % Actual periodic rebuilding of the RT
  on_active({periodic_rt_rebuild}, {Neighbors, OldRT, OldERT, DHTPid}) ->
      % start periodic stabilization
      % log:log(debug, "[ RT ] stabilize"),
      NewRT = ?RT:init_stabilize(Neighbors, OldRT),
      %% ?RT:check(OldRT, NewRT, Neighbors, true),
      NewERT = rt_chord:check_tmp(OldRT, NewRT, OldERT, Neighbors, true), % TODO replace _tmp and rt_chord
      {Neighbors, NewRT, NewERT, DHTPid};
  %% userdevguide-end rt_loop:trigger
  
  % failure detector reported dead node
  on_active({fd_notify, crash, DeadPid, Reason}, {Neighbors, OldRT, OldERT, DHTPid}) ->
      NewRT = ?RT:filter_dead_node(OldRT, DeadPid, Reason),
      %% ?RT:check(OldRT, NewRT, Neighbors, false),
      NewERT = rt_chord:check_tmp(OldRT, NewRT, OldERT, Neighbors, false), % TODO replace _tmp and rt_chord
      {Neighbors, NewRT, NewERT, DHTPid};
  on_active({fd_notify, _Event, _DeadPid, _Reason}, State) ->
      State;
  
  % debug_info for web interface
  on_active({web_debug_info, Requestor},
     {_Neighbors, RT, ERT, _DHTPid} = State) ->
      KeyValueList =
          [{"rt_size", ?RT:get_size(RT)},
           {"ert_size", gb_trees:size(ERT)},
  