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.
I wonder if there is any benefit to calculating maxNodeId using an AtomicInteger rather than the current code structure (of each part calculating its own max id and then once that is done, the max ids being brought together into global max by one thread)