Working version. Not fully tested.