anchor.diff:  testnodes(NumNodes) ->
       [list_to_atom([$n | tl(integer_to_list(1000+N))]) || N <- lists:seq(1, NumNodes)].
   
  -invoke_vbmap(Nodes, NumVBuckets, NumSlaves, NumReplicas) ->
  +invoke_vbmap(Nodes, NumVBuckets, NumSlaves, NumReplicas, Tags) ->
       VbmapName =
           case erlang:system_info(system_architecture) of
               "win32" ->
  
positive.code: 
              try
                  Decoded = ejson:decode(Output),
                  lists:map(
                    fun (Chain) ->
                            Length = length(Chain),
                            [dict:fetch(N, NodesMapping) || N <- Chain] ++
                                lists:duplicate(NumReplicas - Length + 1, undefined)
                    end, Decoded)
              catch
                  E:T ->
                      ?log_error("seems that vbmap produced invalid json (error ~p):~n~s",
                                 [{E, T}, Output]),
                      erlang:raise(E, T, erlang:get_stacktrace())
              end;
          {error, Output} ->
              ?log_error("Could not generate vbucket map: ~s", [Output]),
              exit({vbmap_error, iolist_to_binary(Output)})
      end.
  
  collect_port_output(Port) ->
      do_collect_port_output(Port, []).
  
  do_collect_port_output(Port, Output) ->
      receive
          {Port, {data, Data}} ->
              do_collect_port_output(Port, [Output | Data]);
          {Port, {exit_status, Status}} ->
              case Status of
                  0 ->
                      {ok, Output};
                  _ ->
                      {error, Output}
              end;
          Msg ->
              ?log_error("Got unexpected message"),
              exit({unexpected_message, Msg})
      end.
  
  %%
  %% Tests
  
negative.code:     DiagPath = path_config:tempfile("vbmap_diag", ""),
  
      try
          R = do_invoke_vbmap(VbmapPath, maxflow, DiagPath, Nodes,
                              NumVBuckets, NumSlaves, NumReplicas, Tags),
          case R of
              {ok, Map} ->
                  Map;
              no_solution ->
                  ale:info(?USER_LOGGER,
                           "Couldn't generate rack-aware vbucket map. "
                           "Falling back to rack-unaware one."),
                  {ok, Map} = do_invoke_vbmap(VbmapPath, dummy, DiagPath, Nodes,
                                              NumVBuckets, NumSlaves, NumReplicas, Tags),
                  Map
          end
      after
          file:delete(DiagPath)
      end.
  
  do_invoke_vbmap(VbmapPath, Backend, DiagPath, Nodes,
                  NumVBuckets, NumSlaves, NumReplicas, Tags) ->
      misc:executing_on_new_process(
        fun () ->
                do_invoke_vbmap_body(VbmapPath, Backend, DiagPath, Nodes,
                                     NumVBuckets, NumSlaves, NumReplicas, Tags)
        end).
  
  do_invoke_vbmap_body(VbmapPath, Backend, DiagPath, Nodes,
                       NumVBuckets, NumSlaves, NumReplicas, Tags) ->
      NumNodes = length(Nodes),
  
      Args0 = ["--diag", DiagPath,
               "--output-format", "json",
               "--num-vbuckets", integer_to_list(NumVBuckets),
               "--num-nodes", integer_to_list(NumNodes),
               "--num-slaves", integer_to_list(NumSlaves),
               "--num-replicas", integer_to_list(NumReplicas)],
      Args = vbmap_backend_args(Backend, Nodes, Tags) ++ Args0,
  
      Port = erlang:open_port({spawn_executable, VbmapPath},
                              [stderr_to_stdout, binary,
                               stream, exit_status, hide,
                               {args, Args}]),
  
      PortResult = collect_vbmap_output(Port),
  
      case file:read_file(DiagPath) of
          {ok, Diag} ->
  