refactor and dry up