refactor, add tests