Major rewrite

* Nicer code style
* Better tests
* Various improvements