def search(self, read_cache=True, ssl_verify=True, recid=None, **kwparams):
        """
        Returns records corresponding to the given search query.

        See docstring of invenio.legacy.search_engine.perform_request_search()
        for an overview of available parameters.
        """
        parse_results = False
        of = kwparams.get('of', "")
        if of == "":
            parse_results = True
            of = "xm"
            kwparams['of'] = of
        params = kwparams
        cache_key = (json.dumps(params), parse_results)

        if cache_key not in self.cached_queries or \
                not read_cache:
            if recid:
                results = requests.get(self.server_url + '/record/' + recid,
                                       params=params, cookies=self.cookies,
                                       stream=True, verify=ssl_verify,
                                       allow_redirects=True)
                if results.history:
                    new_recid = urlparse(results.url).path.split('/')[-1]
                    raise InvenioConnectorServerError('The record has been'
                                                      'merged with recid ' +
                                                      new_recid)
            else:
                results = requests.get(self.server_url + "/search",
                                       params=params, cookies=self.cookies,
                                       stream=True, verify=ssl_verify)
            if 'youraccount/login' in results.url:
                # Current user not able to search collection
                raise InvenioConnectorAuthError(
                    "You are trying to search a restricted collection. "
                    "Please authenticate yourself.\n")
        else:
            return self.cached_queries[cache_key]

        if parse_results:
            # FIXME: we should not try to parse if results is string
            parsed_records = self._parse_results(results.raw,
                                                 self.cached_records)
            self.cached_queries[cache_key] = parsed_records
            return parsed_records
        else:
            # pylint: disable=E1103
            # The whole point of the following code is to make sure we can
            # handle two types of variable.
            try:
                res = results.content
            except AttributeError:
                res = results
            # pylint: enable=E1103

            if of == "id":
                try:
                    if isinstance(res, binary_type):
                        # Transform to list
                        res = [int(recid.strip()) for record_id in
                               res.decode('utf-8').strip("[]").split(",")
                               if record_id.strip() != ""]
                    res.reverse()
                except (ValueError, AttributeError):
                    res = []
            self.cached_queries[cache_key] = res
            return res