initial undo/redo with refactor to separate out responsibilities