refactor and add tests; closes #15