Futures version of reading ArrayBasedDirectedGraph

ArrayBasedDirectedGraph was not very clear with `apply()` method on almost 200 lines. I've cut it into submethods and rewrite it to futures instead of ExecutorUtil's parallel works.
Instead of taking an executorService, consider just using FuturePool.unboundedPool. You can take as input just concurrency: Int. This can be used as the input to an AsyncSemaphore which will control parallelism.

The advantage here is that instead of passing around pools of threads custom to different functions, you can use the same underlying threadpool in different places, which grows to as much concurrency as you want.