split it into nice abstract classes with inheritance