lots of refactoring to flatten state