Refactor

I've made quite a few changes to fix bugs and refactor the code. I hope each change is made clear by the commit messages below.