all this stuff looks like it can be factored out, rather than cut-and-pasted.