refactored as separate classes