add tests, finish initial version