private void BufferResource(IntPtr data, int offset, int size) {
            if (size > BufferingParams.MAX_RESOURCE_BYTES_TO_COPY || !_responseBufferingOn) {
                // for long response strings create its own buffer element to avoid copy cost
                // also, when not buffering, no need for an extra copy (nothing will get accumulated anyway)
                _lastBuffer = null;
                _buffers.Add(new HttpResourceResponseElement(data, offset, size));
                return;
            }

            int n;

            // try last buffer
            if (_lastBuffer != null) {
                n = _lastBuffer.Append(data, offset, size);
                size -= n;
                offset += n;
            }

            // do other buffers if needed
            while (size > 0) {
                _lastBuffer = CreateNewMemoryBufferElement();
                _buffers.Add(_lastBuffer);
                n = _lastBuffer.Append(data, offset, size);
                offset += n;
                size -= n;
            }
        }
        private void BufferData(byte[] data, int offset, int size, bool needToCopyData) {
            int n;

            // try last buffer
            if (_lastBuffer != null) {
                n = _lastBuffer.Append(data, offset, size);
                size -= n;
                offset += n;
            }
            else if (!needToCopyData && offset == 0 && !_responseBufferingOn) {
                // when not buffering, there is no need for big buffer accumulating multiple writes
                // the byte[] data can be sent as is

                _buffers.Add(new HttpResponseBufferElement(data, size));
                return;
            }

            // do other buffers if needed
            while (size > 0) {
                _lastBuffer = CreateNewMemoryBufferElement();
                _buffers.Add(_lastBuffer);
                n = _lastBuffer.Append(data, offset, size);
                offset += n;
                size -= n;
            }
        }