Returns the search results info for this command invocation.

        The search results info object is created from the search results info file associated with the command
        invocation.

        :return: Search results info:const:`None`, if the search results info file associated with the command
        invocation is inaccessible.
        :rtype: SearchResultsInfo or NoneType

def search_results_info(self):
        """ Returns the search results info for this command invocation.

        The search results info object is created from the search results info file associated with the command
        invocation.

        :return: Search results info:const:`None`, if the search results info file associated with the command
        invocation is inaccessible.
        :rtype: SearchResultsInfo or NoneType

        """
        if self._search_results_info is not None:
            return self._search_results_info

        if self._protocol_version == 1:
            try:
                path = self._input_header['infoPath']
            except KeyError:
                return None
        else:
            assert self._protocol_version == 2

            try:
                dispatch_dir = self._metadata.searchinfo.dispatch_dir
            except AttributeError:
                return None

            path = os.path.join(dispatch_dir, 'info.csv')

        try:
            with io.open(path, 'r') as f:
                reader = csv.reader(f, dialect=CsvDialect)
                fields = next(reader)
                values = next(reader)
        except IOError as error:
            if error.errno == 2:
                self.logger.error('Search results info file {} does not exist.'.format(json_encode_string(path)))
                return
            raise

        def convert_field(field):
            return (field[1:] if field[0] == '_' else field).replace('.', '_')

        decode = MetadataDecoder().decode

        def convert_value(value):
            try:
                return decode(value) if len(value) > 0 else value
            except ValueError:
                return value

        info = ObjectView(dict(imap(lambda f_v: (convert_field(f_v[0]), convert_value(f_v[1])), izip(fields, values))))

        try:
            count_map = info.countMap
        except AttributeError:
            pass
        else:
            count_map = count_map.split(';')
            n = len(count_map)
            info.countMap = dict(izip(islice(count_map, 0, n, 2), islice(count_map, 1, n, 2)))

        try:
            msg_type = info.msgType
            msg_text = info.msg
        except AttributeError:
            pass
        else:
            messages = ifilter(lambda t_m: t_m[0] or t_m[1], izip(msg_type.split('\n'), msg_text.split('\n')))
            info.msg = [Message(message) for message in messages]
            del info.msgType

        try:
            info.vix_families = ElementTree.fromstring(info.vix_families)
        except AttributeError:
            pass

        self._search_results_info = info
        return info