anchor.diff:      ok.
   
   leave() ->
  -    ns_log:log(?MODULE, 0001, "leaving cluster"),
  -    NewCookie = ns_node_disco:cookie_gen(),
  -    true = erlang:set_cookie(node(), NewCookie),
  -    lists:foreach(fun erlang:disconnect_node/1, nodes()),
  -    ns_config:set(otp, [{cookie, NewCookie}]),
  -    ns_config:set(nodes_wanted, [node()]),
  -    true = exit(ns_server_sup, leave),
  -    ok.
  +    gen_server:cast(?MODULE, leave).
   
  
positive.code: %% API
  -export([join/2, leave/1, leave/0]).
  
  -record(state, {}).
  
  %% gen_server handlers
  start_link() ->
      gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
  
  init([]) ->
      ns_server_sup:start_link(),
      {ok, #state{}}.
  
  handle_call(Request, _From, State) ->
      {reply, {unhandled, ?MODULE, Request}, State}.
  
  handle_cast(Msg, State) ->
      error_logger:error_report("ns_cluster: got unexpected cast ~p~n", Msg),
      {noreply, State}.
  
  handle_info({'EXIT', {join, RemoteNode, NewCookie}}, _State) ->
      true = erlang:set_cookie(node(), NewCookie),
      true = erlang:set_cookie(RemoteNode, NewCookie),
      ns_server_sup:start_link(),
      error_logger:info_msg("ns_cluster: joining cluster~n"),
      {noreply, init([])};
  handle_info({'EXIT', normal}, State) ->
      {stop, normal, State};
  handle_info({'EXIT', Reason}, State) ->
      error_logger:error_report("ns_cluster: got exit ~p and state ~p. Restarting.~n",
                                [Reason, State]),
      {noreply, init([])}.
  
  code_change(_OldVsn, State, _Extra) ->
      {ok, State}.
  
negative.code: 
  %% API
  join(RemoteNode, NewCookie) ->
      gen_server:cast(?MODULE, {join, RemoteNode, NewCookie}).
  
  % Should be invoked on a node that remains in the cluster,
  % where the leaving RemoteNode is passed in as an argument.
  