<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def send_request(self, request):
 """Send the given request and response is required. Use this for messages which have a response message. :param request: request to send :returns: A Future containing the response for the request """

        assert self._handshake_performed, "Perform a handshake first."

        assert request.id not in self._outbound_pending_call, (
            "Message ID '%d' already being used" % request.id
        )

        future = tornado.gen.Future()
        self._outbound_pending_call[request.id] = future
        self.add_pending_outbound()
        self.stream_request(request, future).add_done_callback(
            lambda f: self.remove_pending_outbound()
        )

        if request.ttl:
            self._add_timeout(request, future)

        # the actual future that caller will yield
        response_future = tornado.gen.Future()
        # TODO: fire before_receive_response

        IOLoop.current().add_future(
            future,
            lambda f: self.adapt_result(f, request, response_future),
        )
        return response_future