code: public List<T> waitForAll(List<Future<T>> futures) throws InterruptedException, ExecutionException {
  		Map<Integer, T> results = new HashMap<Integer, T>();
  		int count = futures.size();
  		while(count-- > 0) {
  			int id = queue.take();
  			logger.trace("task '{}' complete (count: {}, queue: {})", id, count, queue.size());
  			T result = futures.get(id).get();
  			results.put(id, result);
  			for(TaskObserver<T> observer : observers) {
  				observer.onTaskComplete(tasks.get(id), result);
  			}
  		}
  		
  		logger.debug("all tasks completed");
  		List<T> values = new ArrayList<T>();
  		for(int i = 0; i < results.size(); ++i) {
  			values.add(results.get(i));
  		}
  		return values;
  	}
docs: Waits for all tasks to complete before returning; if observers are provided,
  they are called each time a task completes.
  
  @param futures
  the list of futures to wait for.
  @param destinations
  an optional set of observers.
  @return
  the list of results, once all tasks are done.
  @throws InterruptedException
  @throws ExecutionException