add most of the snapshot implementation