just an aweful lot of refactoring