lots of refactoring of course