revised code, added tests