anchor.diff:  %%
   %% API
   %%
  +
  +%% @doc Promote a node that's already in the cluster to a peer.
  +promote(Node) ->
  +    gen_server:call({?MODULE, Node}, {promote_self, node()}, 30000).
  +
  +
  +%% @doc Promote *this* node by joining another node.
  +promote_self(OtherNode) ->
  +    gen_server:call(?MODULE, {promote_self, OtherNode}, 30000).
  +
  +
  +%% @doc Demote a peer to a worker. If the node is down, you need to
  +%% eject it.
  +demote(Node) ->
  +    try gen_server:call({?MODULE, Node}, demote_self, 30000)
  +    catch E:R ->
  +            ?log_info("Failed to tell the remote node to demote itself: ~p",
  +                      [{E, R}])
  +    end,
  +    gen_server:call(?MODULE, {demote, Node}).
  +
   
   %% @doc Delete the current mnesia schema for joining/renaming purposes.
   delete_schema() ->
  
positive.code:     %% Don't hang forever if a node goes down when a transaction is in
      %% an unclear state
      application:set_env(mnesia, max_wait_for_decision, 10000),
      ok = mnesia:start(), % Will work even if it's already started
      {ok, _} = mnesia:subscribe(system),
      {ok, _} = mnesia:subscribe({table, schema, detailed}),
      ensure_schema(),
      ?log_info("Current config: ~p", [mnesia:system_info(all)]),
      {ok, #state{}}.
  
  
negative.code:     gen_server:call(?MODULE, {ensure_table, TableName, Opts}).
  
  
  %% @doc Get the list of peer nodes. Returns empty if we're not one;
  %% someone else is responsible for remembering who to talk to in that
  %% case.
  peers() ->
      %% We run this in the server process to make sure mnesia is
      %% actually up.
      gen_server:call(?MODULE, peers).
  
  
  %% @doc Back up the database in preparation for a node rename.
  prepare_rename() ->
      gen_server:call(?MODULE, prepare_rename).
  