Final major rewrite, just need to run more tests.