Rewrite code and fix some bugs