Refactored to include test cases, and to be modular