/// <summary>
        /// Builds the GoAway frame.
        /// </summary>
        /// <param name="lastSeenGoodStreamId">The last seen good stream id.</param>
        /// <param name="reason">The reason of GoAway.</param>
        /// <returns>Builded GoAway Frame</returns>
        public GoAwayFrame BuildGoAwayFrame(int lastSeenGoodStreamId, StatusCode reason)
        {
            GoAwayFrame frame = new GoAwayFrame(lastSeenGoodStreamId, reason);

            frame.Flags  = 0;
            frame.Length = 8;
            return(frame);
        }
        /// <summary>
        /// Deserializes the data into control frame.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns>Deserialized frame.</returns>
        private BaseFrame DeserializeControlFrame(byte[] data)
        {
            FrameType type = GetFrameType(data);
            ControlFrame frame = new ControlFrame();

            switch (type)
            {
                case FrameType.RTS:
                    frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
                    frame.StatusCode = (StatusCode)BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 12, 4));
                    break;
                case FrameType.Headers:
                case FrameType.SynReply:
                    ParseControlFrameHeader(ref frame, data);

                    frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));

                    ParseControlFrameHeaders(ref frame, data, 12);
                    break;
                case FrameType.SynStream:
                    ParseControlFrameHeader(ref frame, data);

                    frame.StreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
                    frame.AssociatedToStreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 12, 4));
                    frame.Priority = (byte)(data[16] >> 5);
                    frame.Slot = data[17];

                    ParseControlFrameHeaders(ref frame, data, 18);
                    break;
                case FrameType.Settings:
                    int numberOfEntries = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
                    frame = new SettingsFrame(numberOfEntries);
                    int headersOffset = 12;

                    for (int i = 0; i < numberOfEntries; i++)
                    {
                        int key = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, headersOffset, 4));
                        headersOffset += 4;
                        int value = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, headersOffset, 4));
                        headersOffset += 4;

                        frame.SettingsHeaders.Add(key, value);
                    }

                    ParseControlFrameHeader(ref frame, data);
                    break;
                case FrameType.GoAway:
                    int lastSeenGoodStreamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
                    StatusCode status = StatusCode.Success;

                    if (data.Length > 12)
                        status = (StatusCode)BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 12, 4));

                    frame = new GoAwayFrame(lastSeenGoodStreamId, status);
                    ParseControlFrameHeader(ref frame, data);
                    break;
                case FrameType.Ping:
                    int streamID = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 4, 4));
                    frame = new ControlFrame { StreamId = streamID };

                    ParseControlFrameHeader(ref frame, data);
                    break;
                case FrameType.WindowUpdate:
                    int streamId = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 4, 4));
                    int deltaWindowSize = BinaryHelper.Int32FromBytes(new ArraySegment<byte>(data, 8, 4));
                    frame = new WindowUpdateFrame(streamId, deltaWindowSize);

                    ParseControlFrameHeader(ref frame, data);
                    break;
            }
            frame.Type = type;

            return frame;
        }
 /// <summary>
 /// Builds the GoAway frame.
 /// </summary>
 /// <param name="lastSeenGoodStreamId">The last seen good stream id.</param>
 /// <param name="reason">The reason of GoAway.</param>
 /// <returns>Builded GoAway Frame</returns>
 public GoAwayFrame BuildGoAwayFrame(int lastSeenGoodStreamId, StatusCode reason)
 {
     GoAwayFrame frame = new GoAwayFrame(lastSeenGoodStreamId, reason);
     frame.Flags = 0;
     frame.Length = 8;
     return frame;
 }