add tests and refactoring