def unpack(cls, data):
        """
        Unpack packed data into an instance

        :param data: Packed data
        :type data: str
        :return: Object instance and remaining data
        :rtype: (APPHeader, str)
        """
        size = struct.calcsize(APPHeader.fmt_header)
        (
            version, msg_type, payload_len,
            timestamp, device_id, flags,
        ), payload = struct.unpack(
            APPHeader.fmt_header, data[:size]
        ), data[size:]
        ack_sequence_number = None
        sequence_number = None

        if flags & Flag.ACKSEQ:
            size = struct.calcsize(APPHeader.fmt_seq_ack)
            (ack_sequence_number,), payload = struct.unpack(
                APPHeader.fmt_seq_ack, payload[:size]
            ), payload[size:]
        if flags & Flag.SEQ:
            size = struct.calcsize(APPHeader.fmt_seq)
            (sequence_number,), payload = struct.unpack(
                APPHeader.fmt_seq, payload[:size]
            ), payload[size:]
        return cls(
            message_type=msg_type,
            version_major=version >> 4,
            version_minor=version & 0xf,
            payload_length=payload_len,
            device_id=device_id,
            sequence_number=sequence_number,
            flags=flags,
            timestamp=timestamp,
            ack_sequence_number=ack_sequence_number
        ), payload