lots of tests and refactoring