Refactor

See commits for more detail

May need more testing, but good base is here.