refactored and some bug fixed