<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def FromLegacyResponses(cls, request=None, responses=None):
 """Creates a Responses object from old style flow request and responses."""

    res = cls()
    res.request = request
    if request:
      res.request_data = rdf_protodict.Dict(request.data)
    dropped_responses = []
    # The iterator that was returned as part of these responses. This should
    # be passed back to actions that expect an iterator.
    res.iterator = None

    if not responses:
      return res

    # This may not be needed if we can assume that responses are
    # returned in lexical order from the data_store.
    responses.sort(key=operator.attrgetter("response_id"))

    if request.HasField("request"):
      client_action_name = request.request.name
      action_registry = server_stubs.ClientActionStub.classes
      if client_action_name not in action_registry:
        raise RuntimeError(
            "Got unknown client action: %s." % client_action_name)
      expected_response_classes = action_registry[
          client_action_name].out_rdfvalues

    old_response_id = None

    # Filter the responses by authorized states
    for msg in responses:
      # Check if the message is authenticated correctly.
      if msg.auth_state != msg.AuthorizationState.AUTHENTICATED:
        logging.warning("%s: Messages must be authenticated (Auth state %s)",
                        msg.session_id, msg.auth_state)
        dropped_responses.append(msg)
        # Skip this message - it is invalid
        continue

      # Handle retransmissions
      if msg.response_id == old_response_id:
        continue

      old_response_id = msg.response_id

      # Check for iterators
      if msg.type == msg.Type.ITERATOR:
        if res.iterator:
          raise ValueError("Received multiple iterator messages at once.")
        res.iterator = rdf_client_action.Iterator(msg.payload)
        continue

      # Look for a status message
      if msg.type == msg.Type.STATUS:
        # Our status is set to the first status message that we see in
        # the responses. We ignore all other messages after that.
        res.status = rdf_flows.GrrStatus(msg.payload)

        # Check this to see if the call succeeded
        res.success = res.status.status == res.status.ReturnedStatus.OK

        # Ignore all other messages
        break

      if msg.type == msg.Type.MESSAGE:
        if request.HasField("request"):
          # Let's do some verification for requests that came from clients.
          if not expected_response_classes:
            raise RuntimeError("Client action %s does not specify out_rdfvalue."
                               % client_action_name)
          else:
            args_rdf_name = msg.args_rdf_name
            if not args_rdf_name:
              raise RuntimeError("Deprecated message format received: "
                                 "args_rdf_name is None.")
            elif args_rdf_name not in [
                x.__name__ for x in expected_response_classes
            ]:
              raise RuntimeError("Response type was %s but expected %s for %s."
                                 % (args_rdf_name, expected_response_classes,
                                    client_action_name))
      # Use this message
      res.responses.append(msg.payload)

    if res.status is None:
      # This is a special case of de-synchronized messages.
      if dropped_responses:
        logging.error(
            "De-synchronized messages detected:\n %s",
            "\n".join([utils.SmartUnicode(x) for x in dropped_responses]))

      res.LogFlowState(responses)

      raise ValueError("No valid Status message.")

    return res