anchor.diff:  -define(TRACE(X,Y), ok).
   -define(TRACE_SEND(Pid, Msg), ?TRACE("[ ~.0p ] to ~.0p: ~.0p)~n", [self(), Pid, Msg])).
   -define(TRACE1(Msg, State), ?TRACE("[ ~.0p ]~n  Msg: ~.0p~n  State: ~.0p)~n", [self(), Msg, State])).
  +-define(TRACE_STATE(State), ?TRACE("[ ~.0p ]~n  State: ~.0p~n", [self(), State])).
   
   -export([join_as_first/3, join_as_other/3,
            process_join_state/2, process_join_msg/2, check_config/0]).
  
positive.code:         [] -> % no candidates -> should not happen in phase4!
              log:log(error, "[ Node ~w ] empty candidate list in join phase 4, "
                          "starting over", [self()]),
              {join, start_over(JoinState), QueuedMessages};
          [Candidate | _Rest] ->
              case lb_op:get(Candidate, id) =:= CandId of
                  false -> State; % unrelated/old message
  
negative.code:                             "[ Node ~w ] node contacted for join is not responsible "
                              "for the selected ID (anymore), trying next candidate",
                              [self()]),
                      NewJoinState = try_next_candidate(JoinState),
                      ?TRACE_STATE(NewJoinState),
                      {join, NewJoinState, QueuedMessages}
              end
      end;
  
  