add unit tests and refactoring