anchor.diff:      end;
   
   handle_cast({remove_node, Node}, #state{waiting = W0} = State) ->
  -    {Alive, Dead} = lists:partition(fun(#job{node=N}) -> N =/= Node end, W0),
  +    {Alive, Dead} = lists:partition(fun(#job{node=N}) -> N =/= Node end, to_list(W0)),
       Dict = remove_entries(State#state.dict, Dead),
       [exit(Pid, die_now) || #job{node=N, pid=Pid} <- State#state.active,
           N =:= Node],
  -    {noreply, State#state{dict = Dict, waiting = Alive}};
  +    {noreply, State#state{dict = Dict, waiting = from_list(Alive)}};
   
   handle_cast({remove_shard, Shard}, #state{waiting = W0} = State) ->
  -    {Alive, Dead} = lists:partition(fun(#job{name=S}) -> S =/= Shard end, W0),
  +    {Alive, Dead} = lists:partition(fun(#job{name=S}) ->
  +                                        S =/= Shard end, to_list(W0)),
       Dict = remove_entries(State#state.dict, Dead),
       [exit(Pid, die_now) || #job{name=S, pid=Pid} <- State#state.active,
           S =:= Shard],
  -    {noreply, State#state{dict = Dict, waiting = Alive}}.
  +    {noreply, State#state{dict = Dict, waiting = from_list(Alive)}}.
   
   handle_info({'EXIT', Pid, _}, #state{update_notifier=Pid} = State) ->
       {ok, NewPid} = start_update_notifier(),
  
positive.code:     [exit(Pid, shutdown) || #job{pid=Pid} <- State#state.active],
      ok.
  
  code_change(_, #state{waiting = [{_,_}|_] = W, active=A} = State, _) ->
      Waiting = [#job{name=Name, node=Node} || {Name,Node} <- W],
      Active = [#job{name=Name, node=Node, pid=Pid} || {Name,Node,Pid} <- A],
      {ok, State#state{active = Active, waiting = Waiting}};
  
  code_change(_, State, _) ->
      {ok, State}.
  
  handle_replication_exit(#state{waiting=[]} = State, Pid) ->
      NewActive = lists:keydelete(Pid, #job.pid, State#state.active),
      {noreply, State#state{active=NewActive, count=length(NewActive)}};
  handle_replication_exit(State, Pid) ->
      #state{active=Active, limit=Limit, dict=D, waiting=Waiting} = State,
      Active1 = lists:keydelete(Pid, #job.pid, Active),
      Count = length(Active1),
      NewState = if Count < Limit ->
          case next_replication(Active1, Waiting) of
          nil -> % all waiting replications are also active
              State#state{active = Active1, count = Count};
          {#job{name=DbName, node=Node} = Job, StillWaiting} ->
              NewPid = start_push_replication(Job),
              State#state{
                  active = [Job#job{pid = NewPid} | Active1],
                  count = Count+1,
                  dict = dict:erase({DbName,Node}, D),
                  waiting = StillWaiting
              }
          end;
      true ->
          State#state{active = Active1, count=Count}
      end,
      {noreply, NewState}.
  
  start_push_replication(#job{name=Name, node=Node}) ->
      spawn_link(mem3_rep, go, [Name, Node]).
  
  add_to_queue(State, #job{name=DbName, node=Node} = Job) ->
      #state{dict=D, waiting=Waiting} = State,
      case dict:is_key({DbName, Node}, D) of
      true ->
          State;
  
negative.code:         twig:log(debug, "adding ~s -> ~p to mem3_sync queue", [DbName, Node]),
          State#state{
              dict = dict:store({DbName,Node}, ok, D),
              waiting = in(Job, WQ)
          }
      end.
  
  