refactored into objects with strategies