<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def fire_event(self, event_name, wait=False, *args, **kwargs):
 """ Fire an event to plugins. PluginManager schedule @asyncio.coroutinecalls for each plugin on method called "on_" + event_name For example, on_connect will be called on event 'connect' Method calls are schedule in the asyn loop. wait parameter must be set to true to wait until all mehtods are completed. :param event_name: :param args: :param kwargs: :param wait: indicates if fire_event should wait for plugin calls completion (True), or not :return: """

        tasks = []
        event_method_name = "on_" + event_name
        for plugin in self._plugins:
            event_method = getattr(plugin.object, event_method_name, None)
            if event_method:
                try:
                    task = self._schedule_coro(event_method(*args, **kwargs))
                    tasks.append(task)

                    def clean_fired_events(future):
                        try:
                            self._fired_events.remove(task)
                        except (KeyError, ValueError):
                            pass

                    task.add_done_callback(clean_fired_events)
                except AssertionError:
                    self.logger.error("Method '%s' on plugin '%s' is not a coroutine" %
                                      (event_method_name, plugin.name))

        self._fired_events.extend(tasks)
        if wait:
            if tasks:
                yield from asyncio.wait(tasks, loop=self._loop)