Address all of #659 and a bit of #874

- see individual commits for details

@DamianEdwards anything else you need to be `protected virtual` or `public` ?

/cc @NTaylorMullen