finished first iteration.  still need to add a few tests, but it seems to work