reorganize code and add test