refactored the code abit, and added some more test case.