Code borrowed from multiple sources.
See CREDITS for more info

Manvendra Bhangui <manvendra@indimail.org>
