simplified a bit to abstract better