anchor.diff:                            [?MODULE, Request, From, State]),
       {reply, {unhandled, ?MODULE, Request}, State}.
   
  +handle_cast({update_progress, Progress}, State) ->
  +    {noreply, State#state{progress=Progress}};
   handle_cast(Msg, State) ->
       error_logger:info_msg("~p:handle_cast(~p, ~p)~n",
                             [?MODULE, Msg, State]),
       {noreply, State}.
   
  -handle_info({rebalance_progress, Progress}, State) ->
  -    {noreply, State#state{rebalance_progress = Progress}};
  +handle_info(janitor, State = #state{bucket=Bucket, rebalancer=undefined}) ->
  +    misc:flush(janitor),
  +    {_, _, Map, Servers} = ns_bucket:config(Bucket),
  +    ns_janitor:cleanup(Bucket, Map, Servers),
  +    {noreply, State};
  +handle_info(rebalance_if_new, State = #state{bucket=Bucket,
  +                                             rebalancer=undefined}) ->
  +    case ns_bucket:config(Bucket) of
  +        {_, _, Map, Servers} when Servers == undefined orelse
  +                                Servers == [] ->
  +            error_logger:info_msg("Performing initial rebalance~n"),
  +            {ok, Pid, Ref} =
  +                misc:spawn_link_safe(
  +                  fun () ->
  +                          spawn_link(
  +                            fun() ->
  +                                    do_rebalance(Bucket, [node()], [], Map)
  +                            end)
  +                  end),
  +            {noreply, State#state{rebalancer={Pid, Ref}, progress=[]}};
  +        _ ->
  +            {noreply, State}
  +    end;
   handle_info({Ref, Reason}, State = #state{rebalancer={_Pid, Ref}}) ->
       error_logger:info_msg("~p:handle_info(): rebalance finished with reason ~p~n",
                             [?MODULE, Reason]),
  
positive.code:         [undefined|_] ->
              error_logger:error_msg("~p:promote_replicas(~p, ~p, ~p, ~p): No master~n", [?MODULE, Bucket, V, RemapNodes, Chain]),
              NewChainExtended;
          [_|_] ->
              NewChainExtended
      end.
  
  histograms(Map, Servers) ->
      Histograms = [lists:keydelete(undefined, 1, misc:uniqc(lists:sort(L))) || L <- misc:rotate(Map)],
      lists:map(fun (H) ->
                        Missing = [{N, 0} || N <- Servers, not lists:keymember(N, 1, H)],
                        Missing ++ H
                end, Histograms).
  
  
negative.code:     RemapNodes = EjectNodes -- AliveNodes, % No active node, promote a replica
      lists:foreach(fun (N) -> ns_cluster:shun(N) end, RemapNodes),
      EvacuateNodes = EjectNodes -- RemapNodes, % Nodes we can move data off of
      Map1 = [promote_replicas(Bucket, V, RemapNodes, Chain) ||
                 {V, Chain} <- misc:enumerate(Map, 0)],
      error_logger:info_msg("Map1 = ~p~n", [Map1]),
      ns_bucket:set_map(Bucket, Map1),
      Histograms1 = histograms(Map1, KeepNodes),
      error_logger:info_msg("Histograms1 = ~p~n", [Histograms1]),
      Moves1 = master_moves(Bucket, EvacuateNodes, Map1, Histograms1),
      error_logger:info_msg("Moves1 = ~p~n", [Moves1]),
      Map2 = perform_moves(Bucket, Map1, Moves1),
      error_logger:info_msg("Map2 = ~p~n", [Map2]),
      Histograms2 = histograms(Map2, KeepNodes),
      error_logger:info_msg("Histograms2 = ~p~n", [Histograms2]),
      Moves2 = balance_masters(Bucket, Map2, Histograms2),
      error_logger:info_msg("Moves2 = ~p~n", [Moves2]),
      Map3 = perform_moves(Bucket, Map2, Moves2),
      error_logger:info_msg("Map3 = ~p~n", [Map3]),
      Histograms3 = histograms(Map3, KeepNodes),
      error_logger:info_msg("Histograms3 = ~p~n", [Histograms3]),
      Map4 = new_replicas(Bucket, EjectNodes, Map3, Histograms3),
      error_logger:info_msg("Map4 = ~p~n", [Map4]),
      lists:foreach(fun (N) -> ns_cluster:shun(N) end, EjectNodes),
      ns_bucket:set_servers(Bucket, KeepNodes),
      ns_bucket:set_map(Bucket, Map4),
      ns_janitor:cleanup(Bucket, Map4, KeepNodes).
  
  master_moves(Bucket, EvacuateNodes, Map, Histograms) ->
      master_moves(Bucket, EvacuateNodes, Map, Histograms, 0, []).
  
  master_moves(_, _, [], _, _, Moves) ->
      Moves;
  master_moves(Bucket, EvacuateNodes, [[OldMaster|_]|MapTail], Histograms, V,
                   Moves) ->
      [MHist|RHists] = Histograms,
      case (OldMaster == undefined) orelse lists:member(OldMaster, EvacuateNodes) of
          true ->
              {NewMaster, MHist1} = assign(MHist, []),
              master_moves(Bucket, EvacuateNodes, MapTail, [MHist1|RHists],
                               V+1, [{V, undefined, NewMaster}|Moves]);
          false ->
              master_moves(Bucket, EvacuateNodes, MapTail, Histograms, V+1,
                               Moves)
      end.
  
  new_replicas(Bucket, EjectNodes, Map, Histograms) ->
      new_replicas(Bucket, EjectNodes, Map, Histograms, 0, []).
  
  new_replicas(_, _, [], _, _, NewMapReversed) ->
      lists:reverse(NewMapReversed);
  new_replicas(Bucket, EjectNodes, [Chain|MapTail], Histograms, V,
                NewMapReversed) ->
      %% Split off the masters - we don't want to move them!
      {[Master|Replicas], [MHist|RHists]} = {Chain, Histograms},
      ChainHist = lists:zip(Replicas, RHists),
  