modify it to deal with generic cases (using a function pointer, a callable object and a object with handlers)