some rather serious refactoring