This is a rewrite of pull request #11 which was a first attempt at this (thanks @xhenner for starting this).