lots of refactoring to simplify code