I've already split this into 3 commits, I have to take it one step at a time :).