made independent of `ListenerMixin`