some refactoring and some redesign