extract some code out into separate classes