a bit more refactoring. trying to make it easier to extend, but I worry that comprehensibility suffers