add comments and some refactoring