docs: def _read_body(stream, decoder, strict=False, logger=None):
      """
      Read an AMF message body from the stream.
  
      @type stream: L{BufferedByteStream<pyamf.util.BufferedByteStream>}
      @param decoder: An AMF0 decoder.
      @param strict: Use strict decoding policy. Default is `False`.
      @param logger: Used to log interesting events whilst reading a remoting
          body.
      @type logger: A C{logging.Logger} instance or C{None}.
      @return: A C{tuple} containing the C{id} of the request and the L{Request}
          or L{Response}
      """
      def _read_args():
          # we have to go through this insanity because it seems that amf0
          # does not keep the array of args in the object references lookup
          type_byte = stream.peek(1)
  
          if type_byte == '\x11':
              if not decoder.use_amf3:
                  raise pyamf.DecodeError(
                      "Unexpected AMF3 type with incorrect message type")
  
              return decoder.readElement()
  
          if type_byte != '\x0a':
              raise pyamf.DecodeError("Array type required for request body")
  
          stream.read(1)
          x = stream.read_ulong()
  
          return [decoder.readElement() for i in xrange(x)]
  
      target = stream.read_utf8_string(stream.read_ushort())
      response = stream.read_utf8_string(stream.read_ushort())
  
      status = STATUS_OK
      is_request = True
  
      for code, s in STATUS_CODES.iteritems():
          if not target.endswith(s):
              continue
  
          is_request = False
          status = code
          target = target[:0 - len(s)]
  
      if logger:
          logger.debug('Remoting target: %r' % (target,))
  
      data_len = stream.read_ulong()
      pos = stream.tell()
  
      if is_request:
          data = _read_args()
      else:
          data = decoder.readElement()
  
      if strict and pos + data_len != stream.tell():
          raise pyamf.DecodeError("Data read from stream does not match body "
              "length (%d != %d)" % (pos + data_len, stream.tell(),))
  
      if is_request:
          return response, Request(target, body=data)
  
      if status == STATUS_ERROR and isinstance(data, pyamf.ASObject):
          data = get_fault(data)
  
      return target, Response(data, status)