DependencyGraph fixes

Pretty major update to the algorithm.

* A single task with lots of dependencies caused some O(N!) behavior and could eat all your memory.
* A particularly fast dependency chain might cause a task to happen before some of its other dependencies.
* "DependencyNode" was hanging out as a mis-named public class.
* Added unit tests.