quite a bit of refactoring and tests
better help