adding unit testing and a bunch of improvements