lots of refactoring