Initial draft.  This took much longer than expected to get right...