refactor the whole code