big patch by David Lamkins, mostly to split the code up.