Finished implementation and tests
Refactored back out to separate files