added unit tests and some refactoring