anchor.diff:                        Missing ++ H
                 end, Histograms).
   
  +
  +%% Tell the orchestrator how many moves are remaining for each node.
  +remaining_moves(Bucket, Moves) ->
  +    gen_server:cast(server(Bucket), {remaining_moves, count_moves(Moves)}).
  +
  +
  +reset_progress(Bucket) ->
  +    gen_server:cast(server(Bucket), reset_progress).
  +
  +
  +%% Tell the orchestrator about the set of moves we're starting.
  +starting_moves(Bucket, Moves) ->
  +    gen_server:cast(server(Bucket), {starting_moves, count_moves(Moves)}).
  +
  +
   server(Bucket) ->
       {global, list_to_atom(lists:flatten(io_lib:format("~s-~s", [?MODULE, Bucket])))}.
   
  
positive.code:             Moves
      end.
  
  do_rebalance(Bucket, KeepNodes, EjectNodes, Map, Tries) ->
      try
          AllNodes = KeepNodes ++ EjectNodes,
          ns_bucket:set_servers(Bucket, AllNodes),
          AliveNodes = ns_node_disco:nodes_actual_proper(),
          RemapNodes = EjectNodes -- AliveNodes, % No active node, promote a replica
          lists:foreach(fun (N) -> ns_cluster:leave(N) end, RemapNodes),
          update_progress(Bucket, AllNodes, 0.1),
          maybe_stop(),
          EvacuateNodes = EjectNodes -- RemapNodes, % Nodes we can move data off of
          Map1 = promote_replicas(Bucket, Map, RemapNodes),
          ns_bucket:set_map(Bucket, Map1),
          update_progress(Bucket, AllNodes, 0.3),
          maybe_stop(),
          Histograms1 = histograms(Map1, KeepNodes),
          Moves1 = master_moves(Bucket, EvacuateNodes, Map1, Histograms1),
          Map2 = perform_moves(Bucket, Map1, Moves1),
          update_progress(Bucket, AllNodes, 0.6),
          maybe_stop(),
          Histograms2 = histograms(Map2, KeepNodes),
          Moves2 = balance_nodes(Bucket, Map2, Histograms2, 1),
          Map3 = perform_moves(Bucket, Map2, Moves2),
          update_progress(Bucket, AllNodes, 0.7),
          maybe_stop(),
          Histograms3 = histograms(Map3, KeepNodes),
          Map4 = new_replicas(Bucket, EjectNodes, Map3, Histograms3),
          ns_bucket:set_map(Bucket, Map4),
          update_progress(Bucket, AllNodes, 0.8),
          maybe_stop(),
          Histograms4 = histograms(Map4, KeepNodes),
          ChainLength = length(lists:nth(1, Map4)),
  
negative.code:     Pid ! stop,
      {reply, ok, State};
  handle_call(stop_rebalance, _From, State) ->
      {reply, not_rebalancing, State}.
  
  
  handle_cast({update_progress, Progress}, #state{progress=Old} = State) ->
      {noreply, State#state{progress=lists:ukeymerge(1, Progress, Old)}};
  handle_cast(reset_progress, State) ->
      {noreply, State#state{progress=[], moves=undefined}};
  handle_cast({remaining_moves, M}, #state{moves=Moves, progress=Progress} =
                  State) ->
      P = [{Node, 1.0 - N / dict:fetch(Node, Moves)} || {Node, N} <- M],
      ?log_info("Remaining moves: ~p, progress: ~p", [M, P]),
      {noreply, State#state{progress=lists:ukeymerge(1, P, Progress)}};
  handle_cast({starting_moves, M}, State) ->
      {noreply, State#state{moves=dict:from_list(M)}}.
  
  handle_info(janitor, State = #state{bucket=Bucket, rebalancer=undefined,
                                      janitor=undefined}) ->
      misc:flush(janitor),
      {_, _, Map, Servers} = ns_bucket:config(Bucket),
      case Servers == undefined orelse Servers == [] of
  