WIP - tidy up code & increase test coverage

Don't merge quite yet, but this is all basically refactoring and adding test code, so we have something clean to work from when we merge @chuong's code in.