See individual commits.
Closes #2501
I think this is easier to read and has more obvious error handling.