public void BitStream_AlignAndByteArray()
        {
            var random = new Random(1293);

            var numbers = new int[1024];

            var payload        = new byte[32];
            var payloadCompare = new byte[32];

            random.NextBytes(payload);

            var buffer = new byte[1024 * 1024];

            for (int runs = 0; runs < 1; ++runs)
            {
                for (int i = 0; i < 1024; ++i)
                {
                    numbers[i] = random.Next(1, 33);
                }

                var output = new BitOutputStream(buffer);
                for (int i = 0; i < 1024; ++i)
                {
                    output.WriteBits((uint)numbers[i], numbers[i]);
                    if (i % 3 == 0)
                    {
                        output.WriteBytes(payload, 0, numbers[i]);
                    }
                }

                var input = new BitInputStream(buffer);
                for (int i = 0; i < 1024; ++i)
                {
                    var value = input.ReadBits(numbers[i]);
                    Assert.AreEqual((uint)numbers[i], value);
                    if (i % 3 == 0)
                    {
                        input.ReadBytes(payloadCompare, 0, numbers[i]);
                        Assert.AreEqual(0, NetworkUtils.MemCmp(payload, 0, payloadCompare, 0, numbers[i]));
                    }
                }
            }
        }
    protected int CompleteSendPackage(TPackageInfo info, ref BitOutputStream output)
    {
        Profiler.BeginSample("NetworkConnection.CompleteSendPackage()");

        info.sentTime = NetworkUtils.stopwatch.ElapsedMilliseconds;
        info.content  = (NetworkMessage)m_PackageBuffer[0];
        int packageSize = output.Flush();

        GameDebug.Assert(packageSize < NetworkConfig.maxPackageSize, "packageSize < NetworkConfig.maxPackageSize");

        if (debugSendStreamWriter != null)
        {
            debugSendStreamWriter.Write(m_PackageBuffer, 0, packageSize);
            debugSendStreamWriter.Write((UInt32)0xedededed);
        }

        if (packageSize > NetworkConfig.packageFragmentSize)
        {
            // Package is too big and needs to be sent as fragments
            var numFragments = packageSize / NetworkConfig.packageFragmentSize;
            //GameDebug.Log("FRAGMENTING: " + connectionId + ": " + packageSize + " (" + numFragments + ")");
            var lastFragmentSize = packageSize % NetworkConfig.packageFragmentSize;
            if (lastFragmentSize != 0)
            {
                ++numFragments;
            }
            else
            {
                lastFragmentSize = NetworkConfig.packageFragmentSize;
            }

            for (var i = 0; i < numFragments; ++i)
            {
                var fragmentSize = i < numFragments - 1 ? NetworkConfig.packageFragmentSize : lastFragmentSize;

                var fragmentOutput = new BitOutputStream(m_FragmentBuffer);
                fragmentOutput.WriteBits((uint)NetworkMessage.FRAGMENT, 8); // Package fragment identifier
                fragmentOutput.WriteBits(Sequence.ToUInt16(outSequence), 16);
                fragmentOutput.WriteBits((uint)numFragments, 8);
                fragmentOutput.WriteBits((uint)i, 8);
                fragmentOutput.WriteBits((uint)fragmentSize, 16);
                fragmentOutput.WriteBytes(m_PackageBuffer, i * NetworkConfig.packageFragmentSize, fragmentSize);
                int fragmentPackageSize = fragmentOutput.Flush();

                transport.SendData(connectionId, m_FragmentBuffer, fragmentPackageSize);
                counters.packagesOut++;
                counters.bytesOut += fragmentPackageSize;
            }
            counters.fragmentedPackagesOut++;
        }
        else
        {
            transport.SendData(connectionId, m_PackageBuffer, packageSize);
            counters.packagesOut++;
            counters.bytesOut += packageSize;
        }

        ++outSequence;

        Profiler.EndSample();

        return(packageSize);
    }