/// <summary>
        /// Serializes the data frame.
        /// </summary>
        /// <param name="frame">The frame.</param>
        /// <returns>Binary representation of the frame.</returns>
        private static byte[] SerializeDataFrame(DataFrame frame)
        {
            var data = new byte[8 + frame.Length];

            BinaryHelper.Int32ToBytes(frame.StreamId, new ArraySegment <byte>(data, 0, 4));
            data[4] = Convert.ToByte(frame.Flags | (frame.IsFinal ? 0x01 : 0x00));
            BinaryHelper.Int32ToBytes(frame.Length, new ArraySegment <byte>(data, 5, 3));
            Buffer.BlockCopy(frame.Data, 0, data, 8, frame.Length);

            return(data);
        }
        private byte[] SerializeControlFrameHeaders(ProtocolHeaders frameHeaders)
        {
            var headers = new List <byte>(256);

            headers.AddRange(BinaryHelper.Int32ToBytes(frameHeaders.Count));
            foreach (KeyValuePair <string, string> pair in frameHeaders)
            {
                byte[] nameBin = Encoding.UTF8.GetBytes(pair.Key);

                headers.AddRange(BinaryHelper.Int32ToBytes(nameBin.Length));
                headers.AddRange(nameBin);

                byte[] valBin = Encoding.UTF8.GetBytes(pair.Value);
                headers.AddRange(BinaryHelper.Int32ToBytes(valBin.Length));

                headers.AddRange(valBin);
            }

            return(headers.ToArray());
        }
        /// <summary>
        /// Serializes the control frame.
        /// </summary>
        /// <param name="frame">The frame.</param>
        /// <returns>Serialized control frame.</returns>
        private byte[] SerializeControlFrame(ControlFrame frame)
        {
            var byteList = new List <byte>();

            byteList.Add((byte)(((frame.Version & 0xFF00) >> 8) | 0x80));
            byteList.Add((byte)(frame.Version & 0x00FF));

            byteList.Add((byte)(((Int16)frame.Type & 0xFF00) >> 8));
            byteList.Add((byte)((Int16)frame.Type & 0x00FF));

            var headersArray = new byte[0];

            switch (frame.Type)
            {
            case FrameType.SynStream:
                byteList.Add(Convert.ToByte(frame.Flags | (frame.IsFinal ? 0x01 : 0x00)));

                headersArray = SerializeControlFrameHeaders(frame.Headers);

                if (headersArray.Length > 0)
                {
                    ProcessorRun(ref headersArray, DirectionProcessType.Outbound, frame.Flags);
                }

                byteList.AddRange(BinaryHelper.Int32ToBytes(headersArray.Length + 10, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));

                byteList.AddRange(BinaryHelper.Int32ToBytes(0));

                byteList.Add(Convert.ToByte(frame.Priority >> 5));

                byteList.Add(Unused);

                break;

            case FrameType.RTS:
                byteList.Add(0);
                byteList.AddRange(BinaryHelper.Int32ToBytes(headersArray.Length + 8, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                byteList.AddRange(BinaryHelper.Int32ToBytes((int)frame.StatusCode));
                break;

            case FrameType.SynReply:
                byteList.Add(frame.Flags);
                headersArray = SerializeControlFrameHeaders(frame.Headers);

                if (headersArray.Length > 0)
                {
                    ProcessorRun(ref headersArray, DirectionProcessType.Outbound, frame.Flags);
                }

                byteList.AddRange(BinaryHelper.Int32ToBytes(headersArray.Length + 4, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                break;

            case FrameType.GoAway:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                byteList.AddRange(BinaryHelper.Int32ToBytes((int)frame.StatusCode));
                break;

            case FrameType.Ping:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                break;

            case FrameType.WindowUpdate:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.StreamId));
                byteList.AddRange(BinaryHelper.Int64ToBytes(((WindowUpdateFrame)frame).DeltaWindowSize));
                break;

            case FrameType.Settings:
                byteList.Add(frame.Flags);
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.Length, 3));
                byteList.AddRange(BinaryHelper.Int32ToBytes(frame.NumberOfEntries));
                break;
            }


            byteList.AddRange(headersArray);
            return(byteList.ToArray());
        }