A complete rewrite, close #24, close #28, close #32, close #35