public unsafe int Bind(NetworkInterfaceEndPoint endpoint)
        {
            var baselib = m_Baselib[0];

            if (m_Baselib[0].m_Socket.handle != IntPtr.Zero)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                AllSockets.OpenSockets.Remove(new SocketList.SocketId
                {
                    socket = m_Baselib[0].m_Socket
                });
#endif
                Binding.Baselib_RegisteredNetwork_Socket_UDP_Close(m_Baselib[0].m_Socket);
                baselib.m_Socket.handle = IntPtr.Zero;

                // Recreate the payloads to make sure we do not loose any items from the queue
                m_PayloadsRx.Dispose();
                m_PayloadsRx = new Payloads(rxQueueSize, maximumPayloadSize);
            }

            var slice = m_LocalAndTempEndpoint.AtIndexAsSlice(0, (uint)Binding.Baselib_RegisteredNetwork_Endpoint_MaxSize);
            UnsafeUtility.MemCpy((void *)slice.data, endpoint.data, endpoint.dataLength);

            var error = default(ErrorState);

            NetworkEndpoint local;
            local.slice = slice;

            Binding.Baselib_NetworkAddress localAddress;
            Binding.Baselib_RegisteredNetwork_Endpoint_GetNetworkAddress(local, &localAddress, error.NativeErrorStatePtr);

            baselib.m_Socket = Binding.Baselib_RegisteredNetwork_Socket_UDP_Create(
                &localAddress,
                Binding.Baselib_NetworkAddress_AddressReuse.Allow,
                checked ((uint)txQueueSize),
                checked ((uint)rxQueueSize),
                error.NativeErrorStatePtr);
            if (error.ErrorCode != ErrorCode.Success)
            {
                m_Baselib[0] = baselib;
                return(-1);
            }

            // Schedule receive right away so we do not loose packets received before the first call to update
            int count    = 0;
            var requests = stackalloc Binding.Baselib_RegisteredNetwork_Request[m_PayloadsRx.Capacity];
            while (m_PayloadsRx.InUse < m_PayloadsRx.Capacity)
            {
                int handle = m_PayloadsRx.AcquireHandle();
                requests[count] = m_PayloadsRx.GetRequestFromHandle(handle);
                requests[count].requestUserdata = (IntPtr)handle + 1;
                ++count;
            }
            if (count > 0)
            {
                Binding.Baselib_RegisteredNetwork_Socket_UDP_ScheduleRecv(
                    baselib.m_Socket,
                    requests,
                    (uint)count,
                    error.NativeErrorStatePtr);
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AllSockets.OpenSockets.Add(new SocketList.SocketId
            {
                socket = baselib.m_Socket
            });
#endif
            m_Baselib[0] = baselib;
            return(0);
        }
            public unsafe void Execute()
            {
                var count       = 0;
                var outstanding = Rx.InUse;
                var error       = default(ErrorState);
                var requests    = stackalloc Binding.Baselib_RegisteredNetwork_Request[Rx.Capacity];

                if (outstanding > 0)
                {
                    var pollCount = 0;
                    while (Binding.Baselib_RegisteredNetwork_Socket_UDP_ProcessRecv(Baselib[0].m_Socket, error.NativeErrorStatePtr) == Binding.Baselib_RegisteredNetwork_ProcessStatus.Pending && pollCount++ < k_defaultRxQueueSize)
                    {
                    }

                    var results = stackalloc Binding.Baselib_RegisteredNetwork_CompletionResult[outstanding];

                    // Pop Completed Requests off the CompletionQ
                    count = (int)Binding.Baselib_RegisteredNetwork_Socket_UDP_DequeueRecv(Baselib[0].m_Socket, results, (uint)outstanding, error.NativeErrorStatePtr);
                    if (error.ErrorCode != ErrorCode.Success)
                    {
                        Receiver.ReceiveErrorCode = (int)error.ErrorCode;
                        return;
                    }

                    // Copy and run Append on each Packet.

                    var stream       = Receiver.GetDataStream();
                    var headerLength = UnsafeUtility.SizeOf <UdpCHeader>();
                    var address      = default(NetworkInterfaceEndPoint);

                    var indicies = stackalloc int[count];
                    for (int i = 0; i < count; i++)
                    {
                        if (results[i].status == Binding.Baselib_RegisteredNetwork_CompletionStatus.Failed)
                        {
                            // todo: report error?
                            continue;
                        }
                        var receivedBytes = (int)results[i].bytesTransferred;
                        var index         = (int)results[i].requestUserdata - 1;
                        var packet        = Rx.GetRequestFromHandle(index);

                        indicies[i] = index;
                        outstanding--;

                        // todo: make sure we avoid this copy
                        var payloadLen = receivedBytes - headerLength;

                        int dataStreamSize = Receiver.GetDataStreamSize();
                        if (Receiver.DynamicDataStreamSize())
                        {
                            while (dataStreamSize + payloadLen >= stream.Length)
                            {
                                stream.ResizeUninitialized(stream.Length * 2);
                            }
                        }
                        else if (dataStreamSize + payloadLen > stream.Length)
                        {
                            Receiver.ReceiveErrorCode = 10040;//(int)ErrorCode.OutOfMemory;
                            continue;
                        }

                        UnsafeUtility.MemCpy(
                            (byte *)stream.GetUnsafePtr() + dataStreamSize,
                            (byte *)packet.payload.data + headerLength,
                            payloadLen);

                        var remote = packet.remoteEndpoint.slice;
                        address.dataLength = (int)remote.size;
                        UnsafeUtility.MemCpy(address.data, (void *)remote.data, (int)remote.size);
                        Receiver.ReceiveCount += Receiver.AppendPacket(address, *(UdpCHeader *)packet.payload.data, receivedBytes);
                    }
                    // Reuse the requests after they have been processed.
                    for (int i = 0; i < count; i++)
                    {
                        requests[i] = Rx.GetRequestFromHandle(indicies[i]);
                        requests[i].requestUserdata = (IntPtr)indicies[i] + 1;
                    }
                }

                while (Rx.InUse < Rx.Capacity)
                {
                    int handle = Rx.AcquireHandle();
                    requests[count] = Rx.GetRequestFromHandle(handle);
                    requests[count].requestUserdata = (IntPtr)handle + 1;
                    ++count;
                }
                if (count > 0)
                {
                    count = (int)Binding.Baselib_RegisteredNetwork_Socket_UDP_ScheduleRecv(
                        Baselib[0].m_Socket,
                        requests,
                        (uint)count,
                        error.NativeErrorStatePtr);
                    if (error.ErrorCode != ErrorCode.Success)
                    {
                        Receiver.ReceiveErrorCode = (int)error.ErrorCode;
                    }
                }
            }