anchor.diff:      frequency(ClusterCommands ++ FaultModelCommands ++ SystemCommands).
   
   %% Picks whether a command should be valid under the current state.
  -precondition(#state{nodes=Nodes, joined_nodes=JoinedNodes}, {call, _Mod, sync_join_cluster, [Node, JoinedNodes]}) -> 
  +precondition(#state{nodes=Nodes, joined_nodes=JoinedNodes}, {call, _Mod, sync_join_cluster, [Node, JoinNode]}) -> 
       %% Only allow dropping of the first unjoined node in the nodes list, for ease of debugging.
       precondition_debug("precondition sync_join_cluster: invoked for node ~p joined_nodes ~p", [Node, JoinedNodes]),
   
  
positive.code: wait_until_nodes_agree_on_membership(Nodes) ->
      AgreementFun = fun(Node) ->
          %% Get membership at node.
          {ok, Members} = rpc:call(?NAME(Node), ?MANAGER, members, []),
  
          %% Convert started nodes to longnames.
          Names = lists:map(fun(N) -> ?NAME(N) end, Nodes),
  
          %% Sort.
          SortedNames = lists:usort(Names),
          SortedMembers = lists:usort(Members),
  
          %% Ensure the lists are the same -- barrier for proceeding.
          case SortedNames =:= SortedMembers of
              true ->
                  debug("node ~p agrees on membership: ~p", 
                        [Node, SortedMembers]),
                  true;
              false ->
                  debug("node ~p disagrees on membership: ~p != ~p", 
                        [Node, SortedMembers, SortedNames]),
                  error
          end
      end,
  
negative.code: 
              case lists:member(Node, CanBeJoinedNodes) of
                  true ->
                      precondition_debug("precondition sync_join_cluster: POSSIBLE YES attempting to join ~p is in ~p", [Node, CanBeJoinedNodes]),
                      lists:member(JoinNode, JoinedNodes);
                  _ ->
                      precondition_debug("precondition sync_join_cluster: NO attempting to join ~p not in ~p", [Node, CanBeJoinedNodes]),
                      false
  