refactored to be more modular