Ported to py3 + unit tests