refactored code, added tests