def request(self, method, url,
        params=None,
        data=None,
        headers=None,
        cookies=None,
        files=None,
        auth=None,
        timeout=None,
        allow_redirects=False,
        proxies=None,
        hooks=None,
        return_response=True,
        config=None,
        prefetch=False):

        """Constructs and sends a :class:`Request <Request>`.
        Returns :class:`Response <Response>` object.

        :param method: method for the new :class:`Request` object.
        :param url: URL for the new :class:`Request` object.
        :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
        :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
        :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
        :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
        :param files: (optional) Dictionary of 'filename': file-like-objects for multipart encoding upload.
        :param auth: (optional) Auth typle to enable Basic/Digest/Custom HTTP Auth.
        :param timeout: (optional) Float describing the timeout of the request.
        :param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed.
        :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
        :param return_response: (optional) If False, an un-sent Request object will returned.
        :param config: (optional) A configuration dictionary.
        :param prefetch: (optional) if ``True``, the response content will be immediately downloaded.
        """

        method = str(method).upper()

        # Default empty dicts for dict params.
        cookies = {} if cookies is None else cookies
        data = {} if data is None else data
        files = {} if files is None else files
        headers = {} if headers is None else headers
        params = {} if params is None else params

        # Expand header values.
        if headers:
            for k, v in headers.items() or {}:
                headers[k] = header_expand(v)

        args = dict(
            method=method,
            url=url,
            data=data,
            params=params,
            headers=headers,
            cookies=cookies,
            files=files,
            auth=auth,
            hooks=hooks,
            timeout=timeout,
            allow_redirects=allow_redirects,
            proxies=proxies,
            config=config,
            _poolmanager=self.poolmanager
        )

        # Merge local kwargs with session kwargs.
        for attr in self.__attrs__:
            session_val = getattr(self, attr, None)
            local_val = args.get(attr)

            args[attr] = merge_kwargs(local_val, session_val)

        # Arguments manipulation hook.
        args = dispatch_hook('args', args['hooks'], args)

        # Create the (empty) response.
        r = Request(**args)

        # Give the response some context.
        r.session = self

        # Don't send if asked nicely.
        if not return_response:
            return r

        # Send the HTTP Request.
        r.send(prefetch=prefetch)

        # Send any cookies back up the to the session.
        self.cookies.update(r.response.cookies)

        # Return the response.
        return r.response