fairly large refactoring