Much needed refactoring + tests