Refactor

Sorry it's a big and hairy PR. Basically it puts the code into (hopefully) easier-to-read chunks and pulls some stuff out into helper functions.