Decodes the incoming stream as a remoting message.

    @type stream: L{BufferedByteStream<pyamf.util.BufferedByteStream>}
    @param strict: Enforce strict decoding. Default is `False`.
    @param logger: Used to log interesting events whilst decoding a remoting
        message.
    @type logger: U{logging.Logger<http://
        docs.python.org/library/logging.html#loggers>}
    @param timezone_offset: The difference between the current timezone and
        UTC. Date/times should always be handled in UTC to avoid confusion but
        this is required for legacy systems.
    @type timezone_offset: U{datetime.datetime.timedelta<http://
        docs.python.org/library/datetime.html#datetime.timedelta}

    @return: Message L{envelope<Envelope>}.

def decode(stream, strict=False, logger=None, timezone_offset=None):
    """
    Decodes the incoming stream as a remoting message.

    @type stream: L{BufferedByteStream<pyamf.util.BufferedByteStream>}
    @param strict: Enforce strict decoding. Default is `False`.
    @param logger: Used to log interesting events whilst decoding a remoting
        message.
    @type logger: U{logging.Logger<http://
        docs.python.org/library/logging.html#loggers>}
    @param timezone_offset: The difference between the current timezone and
        UTC. Date/times should always be handled in UTC to avoid confusion but
        this is required for legacy systems.
    @type timezone_offset: U{datetime.datetime.timedelta<http://
        docs.python.org/library/datetime.html#datetime.timedelta}

    @return: Message L{envelope<Envelope>}.
    """
    if not isinstance(stream, util.BufferedByteStream):
        stream = util.BufferedByteStream(stream)

    if logger:
        logger.debug('remoting.decode start')

    msg = Envelope()
    msg.amfVersion = stream.read_ushort()

    # see http://osflash.org/documentation/amf/envelopes/remoting#preamble
    # why we are doing this...
    if msg.amfVersion > 0x09:
        raise pyamf.DecodeError("Malformed stream (amfVersion=%d)" %
            msg.amfVersion)

    decoder = pyamf.get_decoder(pyamf.AMF0, stream, strict=strict,
        timezone_offset=timezone_offset)
    context = decoder.context

    decoder.use_amf3 = msg.amfVersion == pyamf.AMF3
    header_count = stream.read_ushort()

    for i in xrange(header_count):
        name, required, data = _read_header(stream, decoder, strict)
        msg.headers[name] = data

        if required:
            msg.headers.set_required(name)

    body_count = stream.read_short()

    for i in xrange(body_count):
        context.clear()

        target, payload = _read_body(stream, decoder, strict, logger)
        msg[target] = payload

    if strict and stream.remaining() > 0:
        raise RuntimeError("Unable to fully consume the buffer")

    if logger:
        logger.debug('remoting.decode end')

    return msg