more refactoring to reduce boilerplate