re-factored code and add some comments