a lot of refactoring