This waits until the whole chain of callback methods triggered by
        "trigger_connection_to_rabbit_etc()" has finished, and then starts 
        waiting for publications.
        This is done by starting the ioloop.

        Note: In the pika usage example, these things are both called inside the run()
        method, so I wonder if this check-and-wait here is necessary. Maybe not.
        But the usage example does not implement a Thread, so it probably blocks during
        the opening of the connection. Here, as it is a different thread, the run()
        might get called before the __init__ has finished? I'd rather stay on the
        safe side, as my experience of threading in Python is limited.

def __start_waiting_for_events(self):
        '''
        This waits until the whole chain of callback methods triggered by
        "trigger_connection_to_rabbit_etc()" has finished, and then starts 
        waiting for publications.
        This is done by starting the ioloop.

        Note: In the pika usage example, these things are both called inside the run()
        method, so I wonder if this check-and-wait here is necessary. Maybe not.
        But the usage example does not implement a Thread, so it probably blocks during
        the opening of the connection. Here, as it is a different thread, the run()
        might get called before the __init__ has finished? I'd rather stay on the
        safe side, as my experience of threading in Python is limited.
        '''

        # Start ioloop if connection object ready:
        if self.thread._connection is not None:
            try:
                logdebug(LOGGER, 'Starting ioloop...')
                logtrace(LOGGER, 'ioloop is owned by connection %s...', self.thread._connection)

                # Tell the main thread that we're now open for events.
                # As soon as the thread._connection object is not None anymore, it
                # can receive events.
                self.thread.tell_publisher_to_stop_waiting_for_thread_to_accept_events() 
                self.thread.continue_gently_closing_if_applicable()
                self.thread._connection.ioloop.start()

            except PIDServerException as e:
                raise e

            # It seems that some connection problems do not cause
            # RabbitMQ to call any callback (on_connection_closed
            # or on_connection_error) - it just silently swallows the
            # problem.
            # So we need to manually trigger reconnection to the next
            # host here, which we do by manually calling the callback.
            # We start the ioloop, so it can handle the reconnection events,
            # or also receive events from the publisher in the meantime.


            except Exception as e:
                # This catches any error during connection startup and during the entire
                # time the ioloop runs, blocks and waits for events.

                time_passed = datetime.datetime.now() - self.__start_connect_time
                time_passed_seconds = time_passed.total_seconds()

                # Some pika errors:
                if isinstance(e, pika.exceptions.ProbableAuthenticationError):
                    errorname = self.__make_error_name(e, 'e.g. wrong user or password')

                elif isinstance(e, pika.exceptions.ProbableAccessDeniedError):
                    errorname = self.__make_error_name(e, 'e.g. wrong virtual host name')
                
                elif isinstance(e, pika.exceptions.IncompatibleProtocolError):
                    errorname = self.__make_error_name(e, 'e.g. trying TLS/SSL on wrong port')

                # Other errors:
                else:
                    errorname = self.__make_error_name(e)
                    logdebug(LOGGER, 'Unexpected error during event listener\'s lifetime (after %s seconds): %s', time_passed_seconds, errorname)

                # Now trigger reconnection:
                self.statemachine.set_to_waiting_to_be_available()
                self.on_connection_error(self.thread._connection, errorname)
                self.thread._connection.ioloop.start()
        
        else:
            # I'm quite sure that this cannot happen, as the connection object
            # is created in "trigger_connection_...()" and thus exists, no matter
            # if the actual connection to RabbitMQ succeeded (yet) or not.
            logdebug(LOGGER, 'This cannot happen: Connection object is not ready.')
            logerror(LOGGER, 'Cannot happen. Cannot properly start the thread. Connection object is not ready.')