encapsulate most of the main() logic so that testing actually runs the same code