further further further refactors, still need tests