Execute the tool over the given time interval.

        :param source: The source stream
        :param interval: The time interval
        :param input_plate_value: The value of the plate where data comes from (can be None)
        :type source: Stream
        :type interval: TimeInterval
        :type input_plate_value: tuple[tuple[str, str]] | None
        :return: None

def execute(self, source, interval, input_plate_value):
        """
        Execute the tool over the given time interval.

        :param source: The source stream
        :param interval: The time interval
        :param input_plate_value: The value of the plate where data comes from (can be None)
        :type source: Stream
        :type interval: TimeInterval
        :type input_plate_value: tuple[tuple[str, str]] | None
        :return: None
        """
        if not isinstance(interval, TimeInterval):
            raise TypeError('Expected TimeInterval, got {}'.format(type(interval)))
        # logging.info(self.message(interval))

        output_plate_values = set()

        for item in self._execute(source=source, interval=interval):
            # Join the output meta data with the parent plate meta data
            # meta_data = input_plate_value + (item.meta_data,)
            # sink.writer(item.stream_instance)
            output_plate_values.add(item.meta_data, )

        if not output_plate_values:
            logging.debug("{} did not produce any data for time interval {} on stream {}".format(
                self.name, interval, source))

        self.write_to_history(
            interval=interval,
            tool=self.name,
            document_count=len(output_plate_values)
        )

        return output_plate_values