add tests, and refactoring.