redesigned as a nicer class-based system