/// <summary>
            /// Handles an incomming raw Gds message.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            public void HandleIncoming(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer stream = (ChunkedBuffer)obj;
                long startingPosition = stream.ReadPosition;

                try
                {
                    GdsFrame frame = GdsFrame.ParseFrame(stream.Stream, channel.BufferPool);

                    if (combineChunks)
                    {
                        if (frame.IsComplete)
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);

                            obj = chunkedFrame;
                            chunkedFrame = null;
                        }
                        else
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);
                        }
                    }
                    else
                    {
                        obj = frame;
                    }

                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received Gds message. Body Size: {0}, Type: {1}, IsComplete: {2}", frame.Body.AvailableBytesToRead, Enum.GetName(typeof(GdsFrame.GdsFrameType), frame.Type), frame.IsComplete);
                    }
                }
                catch (EndOfStreamException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (Exception e)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to parse Gds message", e);
                }
            }
            /// <summary>
            /// Updates the given chunked frame with a new frame.
            /// </summary>
            /// <param name="frame"></param>
            private static void UpdateChunk(ref GdsFrame chunkedFrame, GdsFrame frame, ISockNetChannel channel)
            {
                if (chunkedFrame == null)
                {
                    chunkedFrame = frame;  // set initial frame
                }
                else
                {
                    if (frame.Type == GdsFrame.GdsFrameType.Ping || frame.Type == GdsFrame.GdsFrameType.Pong || frame.Type == GdsFrame.GdsFrameType.Close)
                    {
                        chunkedFrame = frame;
                    }

                    GdsFrame.GdsFrameType type = chunkedFrame.Type;

                    ChunkedBuffer body = null;

                    if (frame.Type == GdsFrame.GdsFrameType.BodyOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.HeadersOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        body = new ChunkedBuffer(channel.BufferPool);
                        chunkedFrame.Body.DrainToStreamSync(body.Stream).Close();
                        frame.Body.DrainToStreamSync(body.Stream).Close();
                    }

                    Dictionary<string, byte[]> headers = null;

                    if (frame.Type == GdsFrame.GdsFrameType.HeadersOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.BodyOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        headers = new Dictionary<string, byte[]>(StringComparer.OrdinalIgnoreCase);
                        foreach (KeyValuePair<string, byte[]> kvp in chunkedFrame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                        foreach (KeyValuePair<string, byte[]> kvp in frame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                    }

                    chunkedFrame.Dispose();
                    frame.Dispose();

                    chunkedFrame = GdsFrame.NewContentFrame(frame.StreamId, headers, false, body, frame.IsComplete);
                }
            }
        public ChunkedBuffer ToBuffer(GdsFrame frame)
        {
            ObjectPool<byte[]> pool = new ObjectPool<byte[]>(() => { return new byte[1024]; });

            ChunkedBuffer buffer = new ChunkedBuffer(pool);
            frame.Write(buffer.Stream);
            return buffer;
        }