refactor and fix some bugs