add a complete test suite plus code refactoring