This works okay now.  Could probably use some tidying up, but that's for
a different day.  Also could probably optimize and make more consistent.