Code based on examples by Adam D. Ruppe from http://www.arsdnet.net/dcode/book/chapter_02/03/