split input into two base classes, needs some work to be DRY