Rewrote to support Python 2.5+