refactor and add doc