refactor code and fix some bug