TODO:

* Use native promises if available (should be doing this already)
* See if we can revamp the code a bit to make it cleaner.
* Look into generating documentation.
