refactor and finish