Split out most functionality into separate modules