a bunch of refactoring and some testing