private void HandleEncapsulatedPacket(DataPacket data, EncapsulatedPacket packet)
        {
            if (packet.Flags.Split)
            {
                HandleSplitPacket(packet);
            }
            else
            {
                HandleEncapsulatedPayload(packet.Payload);
            }

            if (packet.Flags.IsReliable())
            {
                SendAcknowledgement(data.Sequence);
            }
        }
        private void HandleSplitPacket(EncapsulatedPacket packet)
        {
            SplitPacket split = null;

            if (!Splits.TryGetValue(packet.SplitId, out split))
            {
                split           = new SplitPacket();
                split.Index     = packet.SplitId;
                split.Available = 0;
                split.Buffers   = new byte[packet.SplitCount][];
                Splits.Add(packet.SplitId, split);
            }

            if (split.Buffers.Length != packet.SplitCount)
            {
                throw new InvalidDataException("Packet split count mismatch");
            }

            if (split.Buffers[packet.SplitIndex] != null)
            {
                return;
            }

            split.Buffers[packet.SplitIndex] = packet.Payload;
            split.Available++;

            if (split.Available == split.Buffers.Length)
            {
                Splits.Remove(split.Index);
                using (var memory = new MemoryStream())
                    using (var stream = new BinaryWriter(memory))
                    {
                        foreach (var buffer in split.Buffers)
                        {
                            stream.Write(buffer);
                        }

                        memory.SetLength(memory.Position);
                        HandleEncapsulatedPayload(memory.ToArray());
                    }
            }
        }
        public void SendEncapsulated(Packet packet, EncapsulatedReliability reliability)
        {
            var dataPkt = new DataPacket();

            dataPkt.Id = (byte)PacketId.EncapsulatedData;
            dataPkt.Sequence.Number = NextPacketId++;

            var encapPkt = new EncapsulatedPacket();

            encapPkt.Flags.Reliability = reliability;
            if (encapPkt.Flags.IsReliable())
            {
                encapPkt.MessageIndex.Number = NextReliableId++;
            }

            if (encapPkt.Flags.IsSequenced())
            {
                encapPkt.SequenceIndex.Number = NextSequenceId++;
            }

            if (encapPkt.Flags.IsSequenced() || encapPkt.Flags.IsOrdered())
            {
                encapPkt.OrderChannel      = 0;
                encapPkt.OrderIndex.Number = NextOrderId++;
            }

            using (var memory = new MemoryStream())
                using (var stream = new BinaryWriterBE(memory))
                {
                    packet.Write(stream);
                    memory.SetLength(memory.Position);
                    encapPkt.Payload = memory.ToArray();
                    encapPkt.Length  = (UInt16)(encapPkt.Payload.Length * 8);
                }

            dataPkt.WrappedPacket = encapPkt;
            Socket.Send(Address, dataPkt);
        }