anchor.diff:  %% States
   %%
   
  -candidate({heartbeat, NodeInfo, master, Data}, #state{peers=Peers} = State) ->
  -    S = update_new_peers(State, NodeInfo, Data),
  +candidate({heartbeat, Node, Type, _H}, State) when is_atom(Node) ->
  +    ?log_warning("Candidate got old-style ~p heartbeat from node ~p. Ignoring.",
  +                 [Type, Node]),
  +    {next_state, candidate, State};
  +
  +candidate({heartbeat, NodeInfo, master, _H}, #state{peers=Peers} = State) ->
       Node = node_info_to_node(NodeInfo),
   
  -    case S#state.master of
  -        Node ->
  -            {next_state, candidate, S#state{last_heard=now()}};
  -        N ->
  -            case lists:member(Node, Peers) of
  +    case lists:member(Node, Peers) of
  +        false ->
  +            ?log_warning("Candidate got master heartbeat from node ~p "
  +                         "which is not in peers ~p", [Node, Peers]),
  +            {next_state, candidate, State};
  +        true ->
  +            %% If master is of strongly lower priority than we are, then we send fake
  +            %% mastership hertbeat to force previous master to surrender. Thus
  +            %% there will be some time when cluster won't have any master
  +            %% node. But after timeout mastership will be taken over by the
  +            %% node with highest priority.
  +            NewState =
  +                case strongly_lower_priority_node(NodeInfo) of
  +                    false ->
  +                        State#state{last_heard=now(), master=Node};
  +                    true ->
  +                        ?log_info("Candidate got master heartbeat from node ~p "
  +                                  "which has lower priority. "
  +                                  "Will try to take over.", [Node]),
  +
  +                        send_heartbeat([Node], master, State),
  +                        State#state{master=undefined}
  +                end,
  +
  +            OldMaster = State#state.master,
  +            NewMaster = NewState#state.master,
  +            case OldMaster =:= NewMaster of
                   true ->
  -                    ?log_info("Changing master from ~p to ~p", [N, Node]),
  -                    {next_state, candidate, S#state{last_heard=now(),
  -                                                    master=Node}};
  +                    ok;
                   false ->
  -                    ?log_warning("Master got master heartbeat from node ~p "
  -                                 "which is not in peers ~p", [Node, Peers]),
  -                    {next_state, candidate, S}
  -            end
  -    end;
  -
  -candidate({heartbeat, NodeInfo, candidate, Data},
  -          #state{peers=Peers} = State) ->
  +                    ?log_info("Changing master from ~p to ~p",
  +                              [OldMaster, NewMaster])
  +            end,
  +            {next_state, candidate, NewState}
  +    end;
  +
  +candidate({heartbeat, NodeInfo, candidate, _H}, #state{peers=Peers} = State) ->
       Node = node_info_to_node(NodeInfo),
  -    S = update_new_peers(State, NodeInfo, Data),
   
       case lists:member(Node, Peers) of
           true ->
  -            case higher_priority_node(NodeInfo, S) of
  +            case higher_priority_node(NodeInfo) of
                   true ->
                       %% Higher priority node
  -                    {next_state, candidate, S#state{last_heard=now()}};
  +                    {next_state, candidate, State#state{last_heard=now()}};
                   false ->
                       %% Lower priority, so ignore it
  -                    {next_state, candidate, S}
  +                    {next_state, candidate, State}
               end;
           false ->
               ?log_warning("Candidate got candidate heartbeat from node ~p which "
                            "is not in peers ~p", [Node, Peers]),
  -            {next_state, candidate, S}
  +            {next_state, candidate, State}
       end;
   
   candidate(Event, State) ->
  
positive.code: %% @private
  %% @doc Send an heartbeat to a list of nodes, except this one.
  send_heartbeat(Nodes, StateName, StateData) ->
      NodeInfo = node_info(StateData),
  
      Args = {heartbeat, NodeInfo, StateName,
              [{peers, StateData#state.peers},
  
negative.code:     end,
      State#state{child = undefined}.
  
  
  %% Auxiliary functions
  
  %% Return node information for ourselves.
  -spec node_info() -> node_info().
  node_info() ->
      RawVersion = ns_info:version(ns_server),
      Version = misc:parse_version(RawVersion),
      {Version, node()}.
  