Forked from the author for further changes.