private static Interop.WebSocket.HttpHeader[] MarshalHttpHeaders(IntPtr nativeHeadersPtr,
                                                                         int nativeHeaderCount)
        {
            Debug.Assert(nativeHeaderCount >= 0, "'nativeHeaderCount' MUST NOT be negative.");
            Debug.Assert(nativeHeadersPtr != IntPtr.Zero || nativeHeaderCount == 0,
                         "'nativeHeaderCount' MUST be 0.");

            Interop.WebSocket.HttpHeader[] httpHeaders = new Interop.WebSocket.HttpHeader[nativeHeaderCount];

            // structure of Interop.WebSocket.HttpHeader:
            //   Name = string*
            //   NameLength = uint*
            //   Value = string*
            //   ValueLength = uint*
            // NOTE - All fields in the object are pointers to the actual value, hence the use of
            //        4 * IntPtr.Size to get to the next header.
            int httpHeaderStructSize = 4 * IntPtr.Size;

            for (int i = 0; i < nativeHeaderCount; i++)
            {
                int    offset = httpHeaderStructSize * i;
                IntPtr currentHttpHeaderPtr = IntPtr.Add(nativeHeadersPtr, offset);
                MarshalAndVerifyHttpHeader(currentHttpHeaderPtr, ref httpHeaders[i]);
            }

            Debug.Assert(httpHeaders != null);
            Debug.Assert(httpHeaders.Length == nativeHeaderCount);

            return(httpHeaders);
        }
        private static void MarshalAndVerifyHttpHeader(IntPtr httpHeaderPtr,
                                                       ref Interop.WebSocket.HttpHeader httpHeader)
        {
            Debug.Assert(httpHeaderPtr != IntPtr.Zero, "'currentHttpHeaderPtr' MUST NOT be IntPtr.Zero.");

            IntPtr httpHeaderNamePtr = Marshal.ReadIntPtr(httpHeaderPtr);
            IntPtr lengthPtr         = IntPtr.Add(httpHeaderPtr, IntPtr.Size);
            int    length            = Marshal.ReadInt32(lengthPtr);

            Debug.Assert(length >= 0, "'length' MUST NOT be negative.");

            if (httpHeaderNamePtr != IntPtr.Zero)
            {
                httpHeader.Name = Marshal.PtrToStringAnsi(httpHeaderNamePtr, length);
            }

            if ((httpHeader.Name == null && length != 0) ||
                (httpHeader.Name != null && length != httpHeader.Name.Length))
            {
                Debug.Fail("The length of 'httpHeader.Name' MUST MATCH 'length'.");
                throw new AccessViolationException();
            }

            // structure of Interop.WebSocket.HttpHeader:
            //   Name = string*
            //   NameLength = uint*
            //   Value = string*
            //   ValueLength = uint*
            // NOTE - All fields in the object are pointers to the actual value, hence the use of
            //        n * IntPtr.Size to get to the correct place in the object.
            int valueOffset  = 2 * IntPtr.Size;
            int lengthOffset = 3 * IntPtr.Size;

            IntPtr httpHeaderValuePtr =
                Marshal.ReadIntPtr(IntPtr.Add(httpHeaderPtr, valueOffset));

            lengthPtr        = IntPtr.Add(httpHeaderPtr, lengthOffset);
            length           = Marshal.ReadInt32(lengthPtr);
            httpHeader.Value = Marshal.PtrToStringAnsi(httpHeaderValuePtr, (int)length);

            if ((httpHeader.Value == null && length != 0) ||
                (httpHeader.Value != null && length != httpHeader.Value.Length))
            {
                Debug.Fail("The length of 'httpHeader.Value' MUST MATCH 'length'.");
                throw new AccessViolationException();
            }
        }
        private static Interop.WebSocket.HttpHeader[] MarshalHttpHeaders(IntPtr nativeHeadersPtr,
            int nativeHeaderCount)
        {
            Debug.Assert(nativeHeaderCount >= 0, "'nativeHeaderCount' MUST NOT be negative.");
            Debug.Assert(nativeHeadersPtr != IntPtr.Zero || nativeHeaderCount == 0,
                "'nativeHeaderCount' MUST be 0.");

            Interop.WebSocket.HttpHeader[] httpHeaders = new Interop.WebSocket.HttpHeader[nativeHeaderCount];

            // structure of Interop.WebSocket.HttpHeader:
            //   Name = string*
            //   NameLength = uint*
            //   Value = string*
            //   ValueLength = uint*
            // NOTE - All fields in the object are pointers to the actual value, hence the use of 
            //        4 * IntPtr.Size to get to the next header. 
            int httpHeaderStructSize = 4 * IntPtr.Size;

            for (int i = 0; i < nativeHeaderCount; i++)
            {
                int offset = httpHeaderStructSize * i;
                IntPtr currentHttpHeaderPtr = IntPtr.Add(nativeHeadersPtr, offset);
                MarshalAndVerifyHttpHeader(currentHttpHeaderPtr, ref httpHeaders[i]);
            }

            Debug.Assert(httpHeaders != null);
            Debug.Assert(httpHeaders.Length == nativeHeaderCount);

            return httpHeaders;
        }