refactor the implementation