conceptually done - lots of bugs, I'm sure