Added tests and refactored into separate modules