fix some bugs, add tests, refactor a bit