improved implementation, added tests