/// <summary>
        /// Add the header field to the dynamic table.
        /// Entries are evicted from the dynamic table until the size of the table
        /// and the new header field is less than the table's capacity.
        /// If the size of the new entry is larger than the table's capacity,
        /// the dynamic table will be cleared.
        /// </summary>
        /// <param name="name">Name.</param>
        /// <param name="value">Value.</param>
        private void Add(byte[] name, byte[] value)
        {
            int headerSize = HeaderField.SizeOf(name, value);

            // Clear the table if the header field size is larger than the capacity.
            if (headerSize > this.capacity)
            {
                this.Clear();
                return;
            }

            // Evict oldest entries until we have enough capacity.
            while (this.size + headerSize > this.capacity)
            {
                this.Remove();
            }

            // Copy name and value that modifications of original do not affect the dynamic table.
            name.CopyTo(name, 0);
            value.CopyTo(value, 0);

            int         h   = Encoder.Hash(name);
            int         i   = Encoder.Index(h);
            HeaderEntry old = headerFields[i];
            HeaderEntry e   = new HeaderEntry(h, name, value, head.Before.Index - 1, old);

            headerFields[i] = e;
            e.AddBefore(head);
            this.size += headerSize;
        }
        /// <summary>
        /// Encode the header field into the header block.
        /// </summary>
        /// <param name="output">Output.</param>
        /// <param name="name">Name.</param>
        /// <param name="value">Value.</param>
        /// <param name="sensitive">If set to <c>true</c> sensitive.</param>
        public void EncodeHeader(BinaryWriter output, byte[] name, byte[] value, bool sensitive)
        {
            // If the header value is sensitive then it must never be indexed
            if (sensitive)
            {
                int nameIndex = this.GetNameIndex(name);
                this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NEVER, nameIndex);
                return;
            }

            // If the peer will only use the static table
            if (this.capacity == 0)
            {
                int staticTableIndex = StaticTable.GetIndex(name, value);
                if (staticTableIndex == -1)
                {
                    int nameIndex = StaticTable.GetIndex(name);
                    this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NONE, nameIndex);
                }
                else
                {
                    Encoder.EncodeInteger(output, 0x80, 7, staticTableIndex);
                }
                return;
            }

            int headerSize = HeaderField.SizeOf(name, value);

            // If the headerSize is greater than the max table size then it must be encoded literally
            if (headerSize > this.capacity)
            {
                int nameIndex = this.GetNameIndex(name);
                this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NONE, nameIndex);
                return;
            }

            HeaderEntry headerField = this.GetEntry(name, value);

            if (headerField != null)
            {
                int index = this.GetIndex(headerField.Index) + StaticTable.Length;
                // Section 6.1. Indexed Header Field Representation
                Encoder.EncodeInteger(output, 0x80, 7, index);
            }
            else
            {
                int staticTableIndex = StaticTable.GetIndex(name, value);
                if (staticTableIndex != -1)
                {
                    // Section 6.1. Indexed Header Field Representation
                    Encoder.EncodeInteger(output, 0x80, 7, staticTableIndex);
                }
                else
                {
                    int nameIndex = this.GetNameIndex(name);
                    if (useIndexing)
                    {
                        this.EnsureCapacity(headerSize);
                    }
                    var indexType = useIndexing ? HPackUtil.IndexType.INCREMENTAL : HPackUtil.IndexType.NONE;
                    this.EncodeLiteral(output, name, value, indexType, nameIndex);
                    if (useIndexing)
                    {
                        this.Add(name, value);
                    }
                }
            }
        }