lots of refactor