anchor.diff:      Fun = binary_to_term(FunBin, [safe]),
       return(Fun(Data)).
   
  +%% send results back to wpool
  +-spec return(any()) -> ok.
   return(Data) ->
       MyPool = pid_groups:get_my(wpool),
       comm:send_local(MyPool, {data, self(), Data}).
  
positive.code:                              [{pid_groups_join_as, DHTNodeGroup, wpool}]).
  
  -spec on(message(), state()) -> state().
  on({do_work, Source, Workload}, {Max, Working, Waiting}) when
          length(Working) >= Max ->
      {Max, Working, lists:append(Waiting, [{Source, Workload}])};
  on({do_work, Source, Workload}, State) ->
      start_worker(Source, Workload, State);
  
  on({'DOWN', _Ref, process, Pid, Reason}, State) ->
      ?TRACE("worker finished with reason ~p~n", [Reason]),
      %% TODO in case of error send some report back
      cleanup_worker(Pid, State);
  
  on({data, Pid, Data}, {_Max, Working, _Waiting} = State) ->
      ?TRACE("wpool: received data from ~p:~n~p...~n",
              [Pid, lists:sublist(Data, 4)]),
  
negative.code:             State
      end.
  
  %% monitor worker and put it into the Working queue
  -spec monitor_worker(pid(), comm:my_pid(), state()) -> state().
  monitor_worker(Pid, Source, {Max, Working, Waiting}) ->
      monitor(process, Pid),
      {Max, [{Pid, Source} | Working], Waiting}.
  
  %% remove worker from Working queue and start a waiting job if present
  -spec cleanup_worker(pid(), state()) -> state().
  cleanup_worker(Pid, {Max, Working, Waiting}) ->
      NewWorking = lists:keydelete(Pid, 1, Working),
      case length(Waiting) of
  