anchor.diff:  % of the task's input file, if the node is not in the task's blacklist.
   % The task may have several redundant inputs, so we need to find the
   % first one that matchs.
  --spec assign_task(task(), [load()], gb_tree(), [node()]) -> gb_tree().
  +-spec assign_task(task(), [load()], gb_tree(), [host()]) -> gb_tree().
   assign_task(Task, NodeStats, Tasks, Nodes) ->
       case Nodes -- Task#task.taskblack of
           [] ->
  
positive.code: 
  % Find first task from any node in Nodes that can be run,
  % i.e. choose_node() =/= false
  -spec find_suitable([task()], node(), [node()], gb_tree(), [node()]) ->
      {ok, task(), node(), node()} | false.
  find_suitable([], _, [], _, _) -> false;
  find_suitable([], _, [Node|R], Tasks, AvailableNodes) ->
      {_, _, L} = gb_trees:get(Node, Tasks),
  
negative.code:             none
      end.
  
  -spec get_empty_nodes(pid(), [host()], non_neg_integer())
                       -> {ok, [host()]} | {error, term()}.
  get_empty_nodes(Job, AvailableNodes, Timeout) ->
      gen_server:call(Job, {get_empty_nodes, AvailableNodes}, Timeout).
  
  % Return an often empty subset of AvailableNodes that don't have any tasks
  % assigned to them by any job.
  -spec all_empty_nodes([jobinfo()], [host()]) -> [host()].
  all_empty_nodes(_, []) -> [];
  all_empty_nodes([], AvailableNodes) -> AvailableNodes;
  all_empty_nodes([Job|Jobs], AvailableNodes) ->
  