Han's and David's code integrated. Not tested, may have some problems
that need to be worked out.