Fetches all Requests and Responses for a given session_id.

def ReadRequestsAndResponses(self,
                               session_id,
                               timestamp=None,
                               request_limit=None,
                               response_limit=None):
    """Fetches all Requests and Responses for a given session_id."""
    subject = session_id.Add("state")
    requests = {}

    # Get some requests.
    for predicate, serialized, _ in self.ResolvePrefix(
        subject,
        self.FLOW_REQUEST_PREFIX,
        limit=request_limit,
        timestamp=timestamp):

      request_id = predicate.split(":", 1)[1]
      requests[str(subject.Add(request_id))] = serialized

    # And the responses for them.
    response_data = dict(
        self.MultiResolvePrefix(
            list(iterkeys(requests)),
            self.FLOW_RESPONSE_PREFIX,
            limit=response_limit,
            timestamp=timestamp))

    for urn, request_data in sorted(iteritems(requests)):
      request = rdf_flow_runner.RequestState.FromSerializedString(request_data)
      responses = []
      for _, serialized, timestamp in response_data.get(urn, []):
        msg = rdf_flows.GrrMessage.FromSerializedString(serialized)
        msg.timestamp = timestamp
        responses.append(msg)

      yield (request, sorted(responses, key=lambda msg: msg.response_id))