refactor and unit tests