ported to py3 + unit tests