ported to python 3. tested on py2.7, py3.2, py3.3, pypy