refactoring and add some features