This is going to be a bit more comprehensive than anticipated. In order
to cleanly refactor the core and the engine, basically start from
scratch with the implementation.
Goals:
* Test coverage
* Maintain backwards compatibility with module interface as much as
possible (but still make modules easier to code)
* Simplicity
see #23