anchor.diff:  %% based on node states of all nodes.
   %% @end
   %%--------------------------------------------------------------------
  --spec choose_node_for_dispatcher(DSNAdvice :: #dispatcher_lb_advice{}, WorkerName::atom()) -> node().
  +-spec choose_node_for_dispatcher(DSNAdvice :: #dispatcher_lb_advice{}, WorkerName :: atom()) -> node().
   choose_node_for_dispatcher(Advice, WorkerName) ->
       #dispatcher_lb_advice{should_delegate = ShouldDelegate,
           nodes_and_frequency = NodesAndFreq} = Advice,
  
positive.code:     LoadsForDNS = [load_for_dns(NodeState) || NodeState <- NodeStates],
      MinLoadForDNS = lists:min(LoadsForDNS),
      LoadsAndNodes = lists:zip(LoadsForDNS, NodesAndIPs),
      NotOverloaded = lists:filter(
          fun({Load, _}) ->
              not overloaded_for_dns(Load, MinLoadForDNS)
          end, LoadsAndNodes),
  
      % TODO testy
      lists:foreach(
          fun({_, {Node, _}}) ->
              io:format("[DNS] excluding ~p~n", [Node])
          end, LoadsAndNodes -- NotOverloaded),
  
      % Calculate how often should given nodes appear in the first row in DNS
      % responses. The bigger the load, the less often should the node appear.
      NodesAndFrequency = [{NodeIP, MinLoadForDNS / Load} || {Load, {_, NodeIP}} <- NotOverloaded],
      FrequencySum = lists:foldl(fun({_, Freq}, Acc) -> Acc + Freq end, 0.0, NodesAndFrequency),
      NormalizedNodesAndFrequency = [{NodeIP, Freq / FrequencySum} || {NodeIP, Freq} <- NodesAndFrequency],
      NodeChoices = [NodeIP || {NodeIP, _} <- NormalizedNodesAndFrequency],
  
negative.code:             {Node, #dispatcher_lb_advice{should_delegate = ShouldDelegate,
                  nodes_and_frequency = NodesAndFrequency, all_nodes = Nodes}}
          end, LoadsAndNodes),
      % Calculate expected extra loads on each node. For example:
      % node A is overloaded and will delegate 70% reqs to node B
      % node B in not overloaded
      % expected extra load on each node is:
      % node A = 0.0
      %                0.7 * node_A_load
      % node B = -------------------------------
      %          node_B_load + 0.7 * node_A_load
      %
      ExtraLoadsSum = lists:foldl(
          fun({NodeFrom, DispLBAdvice}, ExtraLoadsAcc) ->
              #dispatcher_lb_advice{
                  should_delegate = ShouldDelegate,
                  nodes_and_frequency = NodesAndFreq} = DispLBAdvice,
              case ShouldDelegate of
                  false ->
                      ExtraLoadsAcc;
                  true ->
                      lists:foldl(
                          fun({NodeTo, Freq}, Acc) ->
                              case NodeFrom of
                                  NodeTo ->
                                      Acc;
                                  _ ->
                                      Current = proplists:get_value(NodeTo, Acc, 0.0),
                                      NodeToLoad = proplists:get_value(NodeTo, LoadsAndNodes, 0.0),
                                      [{NodeTo, Current + NodeToLoad * Freq} | proplists:delete(NodeTo, Acc)]
                              end
                          end, ExtraLoadsAcc, NodesAndFreq)
              end
          end, [], Result),
      ?dump(ExtraLoadsSum),
      NewExtraLoads = lists:map(
          fun({Node, ExtraLoadSum}) ->
              NodeLoad = proplists:get_value(Node, LoadsAndNodes, 0.0),
              ExtraLoadsSum / (NodeLoad + ExtraLoadsSum)
          end, ExtraLoadsSum),
      ?dump(NewExtraLoads),
      {Result, LBState#load_balancing_state{expected_extra_load = NewExtraLoads}}.
  
  
  %%--------------------------------------------------------------------
  