add tests, refactor code