static byte EncodeSubscribePacket(MqttSubscribePacket packet, IMqttPacketWriter packetWriter)
        {
            if (packet.TopicFilters?.Any() != true)
            {
                throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.8.3-3].");
            }

            ThrowIfPacketIdentifierIsInvalid(packet.PacketIdentifier, packet);

            packetWriter.Write(packet.PacketIdentifier);

            var propertiesWriter = new MqttV500PropertiesWriter();

            if (packet.Properties != null)
            {
                propertiesWriter.WriteSubscriptionIdentifier(packet.Properties.SubscriptionIdentifier);
                propertiesWriter.WriteUserProperties(packet.Properties.UserProperties);
            }

            propertiesWriter.WriteTo(packetWriter);

            if (packet.TopicFilters?.Count > 0)
            {
                foreach (var topicFilter in packet.TopicFilters)
                {
                    packetWriter.WriteWithLengthPrefix(topicFilter.Topic);

                    var options = (byte)topicFilter.QualityOfServiceLevel;

                    if (topicFilter.NoLocal == true)
                    {
                        options |= 1 << 2;
                    }

                    if (topicFilter.RetainAsPublished == true)
                    {
                        options |= 1 << 3;
                    }

                    if (topicFilter.RetainHandling.HasValue)
                    {
                        options |= (byte)((byte)topicFilter.RetainHandling.Value << 4);
                    }

                    packetWriter.Write(options);
                }
            }

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.Subscribe, 0x02));
        }