refactory the code and fix some bugs