Refactor, restructure, and add tests