refactor and added tests