add lots of tests, fix bugs