anchor.diff:          [{capture, all_but_first, binary}]
       ),
       OpName = case Op of move -> move2; _ -> Op end,
  -    io:format("clou shard ~s ~s ~s ~s ~s ~s ~s~n", [OpName, Cluster, Account, DbName,
  -         Range, SourceId, TargetId]),
  +    case get(fd) of
  +        undefined ->
  +            io:format("clou shard ~s ~s ~s ~s ~s ~s ~s~n", [OpName,
  +                 Cluster, Account, DbName, Range, SourceId, TargetId]);
  +        FD ->
  +            io:format(FD, "clou shard ~s ~s ~s ~s ~s ~s ~s~n", [OpName,
  +                 Cluster, Account, DbName, Range, SourceId, TargetId])
  +    end,
       Operation;
   
   print(Operations) when is_list(Operations) ->
  
positive.code: %% @doc Expands a cluster without requiring each DB to be optimally balanced.
  -spec expand(integer() | global) -> [{atom(), #shard{}, node()}].
  expand(global) ->
      global_expand(surviving_nodes(), [], 1000);
  
  %% @doc Expands all databases in the cluster, stopping at Limit operations.
  expand(Limit) when is_integer(Limit), Limit > 0 ->
      TargetNodes = surviving_nodes(),
      LocalBalanceFun = fun(Db, Moves) -> expand(Db, TargetNodes, Moves) end,
      LocalBalanceOps = apply_to_cluster(LocalBalanceFun, Limit),
  
negative.code: %% @doc Computes a plan to remove up to Limit shards from nodes in "decom" zone.
  -spec contract(integer()) -> [{atom(), #shard{}, node()}].
  contract(Limit) when is_integer(Limit), Limit > 0 ->
      {ok, FD} = file:open("/tmp/rebalance_plan.txt", [write]),
      erlang:put(fd, FD),
      TargetNodes = surviving_nodes(),
      apply_to_cluster(fun(Db, Moves) -> contract(Db, TargetNodes, Moves) end, Limit);
  
  