refactored into many smaller classes