using System;
using System.Collections;
using System.Text;
using System.ComponentModel;
using System.Xml.Serialization;

namespace CodeSmith.CustomProperties
{
    #region Interface IStringCollection

    /// <summary>
    /// Defines size, enumerators, and synchronization methods for strongly
    /// typed collections of <see cref="String"/> elements.
    /// </summary>
    /// <remarks>
    /// <b>IStringCollection</b> provides an <see cref="ICollection"/>
    /// that is strongly typed for <see cref="String"/> elements.
    /// </remarks>

    public interface IStringCollection
    {
        #region Properties
        #region Count

        /// <summary>
        /// Gets the number of elements contained in the
        /// <see cref="IStringCollection"/>.
        /// </summary>
        /// <value>The number of elements contained in the
        /// <see cref="IStringCollection"/>.</value>
        /// <remarks>Please refer to <see cref="ICollection.Count"/> for details.</remarks>

        int Count { get; }

        #endregion
        #region IsSynchronized

        /// <summary>
        /// Gets a value indicating whether access to the
        /// <see cref="IStringCollection"/> is synchronized (thread-safe).
        /// </summary>
        /// <value><c>true</c> if access to the <see cref="IStringCollection"/> is
        /// synchronized (thread-safe); otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="ICollection.IsSynchronized"/> for details.</remarks>

        bool IsSynchronized { get; }

        #endregion
        #region SyncRoot

        /// <summary>
        /// Gets an object that can be used to synchronize access
        /// to the <see cref="IStringCollection"/>.
        /// </summary>
        /// <value>An object that can be used to synchronize access
        /// to the <see cref="IStringCollection"/>.</value>
        /// <remarks>Please refer to <see cref="ICollection.SyncRoot"/> for details.</remarks>

        object SyncRoot { get; }

        #endregion
        #endregion
        #region Methods
        #region CopyTo

        /// <summary>
        /// Copies the entire <see cref="IStringCollection"/> to a one-dimensional <see cref="Array"/>
        /// of <see cref="String"/> elements, starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the
        /// <see cref="String"/> elements copied from the <see cref="IStringCollection"/>.
        /// The <b>Array</b> must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in <paramref name="array"/>
        /// at which copying begins.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="array"/> is a null reference.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="arrayIndex"/> is less than zero.</exception>
        /// <exception cref="ArgumentException"><para>
        /// <paramref name="arrayIndex"/> is equal to or greater than the length of <paramref name="array"/>.
        /// </para><para>-or-</para><para>
        /// The number of elements in the source <see cref="IStringCollection"/> is greater
        /// than the available space from <paramref name="arrayIndex"/> to the end of the destination
        /// <paramref name="array"/>.</para></exception>
        /// <remarks>Please refer to <see cref="ICollection.CopyTo"/> for details.</remarks>

        void CopyTo(String[] array, int arrayIndex);

        #endregion
        #region GetEnumerator

        /// <summary>
        /// Returns an <see cref="IStringEnumerator"/> that can
        /// iterate through the <see cref="IStringCollection"/>.
        /// </summary>
        /// <returns>An <see cref="IStringEnumerator"/>
        /// for the entire <see cref="IStringCollection"/>.</returns>
        /// <remarks>Please refer to <see cref="IEnumerable.GetEnumerator"/> for details.</remarks>

        IStringEnumerator GetEnumerator();

        #endregion
        #endregion
    }

    #endregion
    #region Interface IStringList

    /// <summary>
    /// Represents a strongly typed collection of <see cref="String"/>
    /// objects that can be individually accessed by index.
    /// </summary>
    /// <remarks>
    /// <b>IStringList</b> provides an <see cref="IList"/>
    /// that is strongly typed for <see cref="String"/> elements.
    /// </remarks>

    public interface
        IStringList : IStringCollection
    {
        #region Properties
        #region IsFixedSize

        /// <summary>
        /// Gets a value indicating whether the <see cref="IStringList"/> has a fixed size.
        /// </summary>
        /// <value><c>true</c> if the <see cref="IStringList"/> has a fixed size;
        /// otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="IList.IsFixedSize"/> for details.</remarks>

        bool IsFixedSize { get; }

        #endregion
        #region IsReadOnly

        /// <summary>
        /// Gets a value indicating whether the <see cref="IStringList"/> is read-only.
        /// </summary>
        /// <value><c>true</c> if the <see cref="IStringList"/> is read-only;
        /// otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="IList.IsReadOnly"/> for details.</remarks>

        bool IsReadOnly { get; }

        #endregion
        #region Item

        /// <summary>
        /// Gets or sets the <see cref="String"/> element at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the
        /// <see cref="String"/> element to get or set.</param>
        /// <value>
        /// The <see cref="String"/> element at the specified <paramref name="index"/>.
        /// </value>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than
        /// <see cref="IStringCollection.Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// The property is set and the <see cref="IStringList"/> is read-only.</exception>
        /// <remarks>Please refer to <see cref="IList.this"/> for details.</remarks>

        String this[int index] { get; set; }

        #endregion
        #endregion
        #region Methods
        #region Add

        /// <summary>
        /// Adds a <see cref="String"/> to the end
        /// of the <see cref="IStringList"/>.
        /// </summary>
        /// <param name="value">The <see cref="String"/> object
        /// to be added to the end of the <see cref="IStringList"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <returns>The <see cref="IStringList"/> index at which
        /// the <paramref name="value"/> has been added.</returns>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.Add"/> for details.</remarks>

        int Add(String value);

        #endregion
        #region Clear

        /// <summary>
        /// Removes all elements from the <see cref="IStringList"/>.
        /// </summary>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.Clear"/> for details.</remarks>

        void Clear();

        #endregion
        #region Contains

        /// <summary>
        /// Determines whether the <see cref="IStringList"/>
        /// contains the specified <see cref="String"/> element.
        /// </summary>
        /// <param name="value">The <see cref="String"/> object
        /// to locate in the <see cref="IStringList"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <returns><c>true</c> if <paramref name="value"/> is found in the
        /// <see cref="IStringList"/>; otherwise, <c>false</c>.</returns>
        /// <remarks>Please refer to <see cref="IList.Contains"/> for details.</remarks>

        bool Contains(String value);

        #endregion
        #region IndexOf

        /// <summary>
        /// Returns the zero-based index of the first occurrence of the specified
        /// <see cref="String"/> in the <see cref="IStringList"/>.
        /// </summary>
        /// <param name="value">The <see cref="String"/> object
        /// to locate in the <see cref="IStringList"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <returns>
        /// The zero-based index of the first occurrence of <paramref name="value"/>
        /// in the <see cref="IStringList"/>, if found; otherwise, -1.
        /// </returns>
        /// <remarks>Please refer to <see cref="IList.IndexOf"/> for details.</remarks>

        int IndexOf(String value);

        #endregion
        #region Insert

        /// <summary>
        /// Inserts a <see cref="String"/> element into the
        /// <see cref="IStringList"/> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which
        /// <paramref name="value"/> should be inserted.</param>
        /// <param name="value">The <see cref="String"/> object
        /// to insert into the <see cref="IStringList"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is greater than
        /// <see cref="IStringCollection.Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.Insert"/> for details.</remarks>

        void Insert(int index, String value);

        #endregion
        #region Remove

        /// <summary>
        /// Removes the first occurrence of the specified <see cref="String"/>
        /// from the <see cref="IStringList"/>.
        /// </summary>
        /// <param name="value">The <see cref="String"/> object
        /// to remove from the <see cref="IStringList"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.Remove"/> for details.</remarks>

        void Remove(String value);

        #endregion
        #region RemoveAt

        /// <summary>
        /// Removes the element at the specified index of the
        /// <see cref="IStringList"/>.
        /// </summary>
        /// <param name="index">The zero-based index of the element to remove.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than
        /// <see cref="IStringCollection.Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.RemoveAt"/> for details.</remarks>

        void RemoveAt(int index);

        #endregion
        #endregion
    }

    #endregion
    #region Interface IStringEnumerator

    /// <summary>
    /// Supports type-safe iteration over a collection that
    /// contains <see cref="String"/> elements.
    /// </summary>
    /// <remarks>
    /// <b>IStringEnumerator</b> provides an <see cref="IEnumerator"/>
    /// that is strongly typed for <see cref="String"/> elements.
    /// </remarks>

    public interface IStringEnumerator
    {
        #region Properties
        #region Current

        /// <summary>
        /// Gets the current <see cref="String"/> element in the collection.
        /// </summary>
        /// <value>The current <see cref="String"/> element in the collection.</value>
        /// <exception cref="InvalidOperationException"><para>The enumerator is positioned
        /// before the first element of the collection or after the last element.</para>
        /// <para>-or-</para>
        /// <para>The collection was modified after the enumerator was created.</para></exception>
        /// <remarks>Please refer to <see cref="IEnumerator.Current"/> for details, but note
        /// that <b>Current</b> fails if the collection was modified since the last successful
        /// call to <see cref="MoveNext"/> or <see cref="Reset"/>.</remarks>

        String Current { get; }

        #endregion
        #endregion
        #region Methods
        #region MoveNext

        /// <summary>
        /// Advances the enumerator to the next element of the collection.
        /// </summary>
        /// <returns><c>true</c> if the enumerator was successfully advanced to the next element;
        /// <c>false</c> if the enumerator has passed the end of the collection.</returns>
        /// <exception cref="InvalidOperationException">
        /// The collection was modified after the enumerator was created.</exception>
        /// <remarks>Please refer to <see cref="IEnumerator.MoveNext"/> for details.</remarks>

        bool MoveNext();

        #endregion
        #region Reset

        /// <summary>
        /// Sets the enumerator to its initial position,
        /// which is before the first element in the collection.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// The collection was modified after the enumerator was created.</exception>
        /// <remarks>Please refer to <see cref="IEnumerator.Reset"/> for details.</remarks>

        void Reset();

        #endregion
        #endregion
    }

    #endregion
    #region Interface IStringStringCollection

    /// <summary>
    /// Defines size, enumerators, and synchronization methods for strongly
    /// typed collections of <see cref="NameValueEntry"/> elements.
    /// </summary>
    /// <remarks>
    /// <b>IStringStringCollection</b> provides an <see cref="ICollection"/>
    /// that is strongly typed for <see cref="NameValueEntry"/> elements.
    /// </remarks>

    public interface IStringStringCollection
    {
        #region Properties
        #region Count

        /// <summary>
        /// Gets the number of elements contained in the
        /// <see cref="IStringStringCollection"/>.
        /// </summary>
        /// <value>The number of elements contained in the
        /// <see cref="IStringStringCollection"/>.</value>
        /// <remarks>Please refer to <see cref="ICollection.Count"/> for details.</remarks>

        int Count { get; }

        #endregion
        #region IsSynchronized

        /// <summary>
        /// Gets a value indicating whether access to the
        /// <see cref="IStringStringCollection"/> is synchronized (thread-safe).
        /// </summary>
        /// <value><c>true</c> if access to the <see cref="IStringStringCollection"/>
        /// is synchronized (thread-safe); otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="ICollection.IsSynchronized"/> for details.</remarks>

        bool IsSynchronized { get; }

        #endregion
        #region SyncRoot

        /// <summary>
        /// Gets an object that can be used to synchronize access
        /// to the <see cref="IStringStringCollection"/>.
        /// </summary>
        /// <value>An object that can be used to synchronize access to the
        /// <see cref="IStringStringCollection"/>.</value>
        /// <remarks>Please refer to <see cref="ICollection.SyncRoot"/> for details.</remarks>

        object SyncRoot { get; }

        #endregion
        #endregion
        #region Methods
        #region CopyTo

        /// <summary>
        /// Copies the entire <see cref="IStringStringCollection"/>
        /// to a one-dimensional <see cref="Array"/> of <see cref="NameValueEntry"/> elements,
        /// starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">The one-dimensional <see cref="Array"/> that is the
        /// destination of the <see cref="NameValueEntry"/> elements copied from the
        /// <see cref="IStringStringCollection"/>.
        /// The <b>Array</b> must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in <paramref name="array"/>
        /// at which copying begins.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="array"/> is a null reference.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="arrayIndex"/> is less than zero.</exception>
        /// <exception cref="ArgumentException"><para>
        /// <paramref name="arrayIndex"/> is equal to or greater than the length of <paramref name="array"/>.
        /// </para><para>-or-</para><para>
        /// The number of elements in the source <see cref="IStringStringCollection"/>
        /// is greater than the available space from <paramref name="arrayIndex"/> to the end of the
        /// destination <paramref name="array"/>.</para></exception>
        /// <remarks>Please refer to <see cref="ICollection.CopyTo"/> for details.</remarks>

        void CopyTo(NameValueEntry[] array, int arrayIndex);

        #endregion
        #region GetEnumerator

        /// <summary>
        /// Returns an <see cref="IStringStringEnumerator"/> that can
        /// iterate through the <see cref="IStringStringCollection"/>.
        /// </summary>
        /// <returns>An <see cref="IStringStringEnumerator"/>
        /// for the entire <see cref="IStringStringCollection"/>.</returns>
        /// <remarks>Please refer to <see cref="IEnumerable.GetEnumerator"/> for details.</remarks>

        IStringStringEnumerator GetEnumerator();

        #endregion
        #endregion
    }

    #endregion
    #region Interface IStringStringDictionary

    /// <summary>
    /// Represents a strongly typed collection of
    /// <see cref="NameValueEntry"/> key-and-value pairs.
    /// </summary>
    /// <remarks>
    /// <b>IStringStringDictionary</b> provides an
    /// <see cref="IDictionary"/> that is strongly typed for
    /// <see cref="String"/> keys and <see cref="String"/> values.
    /// </remarks>

    public interface
        IStringStringDictionary : IStringStringCollection
    {
        #region Properties
        #region IsFixedSize

        /// <summary>
        /// Gets a value indicating whether the
        /// <see cref="IStringStringDictionary"/> has a fixed size.
        /// </summary>
        /// <value><c>true</c> if the <see cref="IStringStringDictionary"/>
        /// has a fixed size; otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="IDictionary.IsFixedSize"/> for details.</remarks>

        bool IsFixedSize { get; }

        #endregion
        #region IsReadOnly

        /// <summary>
        /// Gets a value indicating whether the
        /// <see cref="IStringStringDictionary"/> is read-only.
        /// </summary>
        /// <value><c>true</c> if the <see cref="IStringStringDictionary"/>
        /// is read-only; otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="IDictionary.IsReadOnly"/> for details.</remarks>

        bool IsReadOnly { get; }

        #endregion
        #region Item

        /// <summary>
        /// Gets or sets the <see cref="String"/> value
        /// associated with the specified <see cref="String"/> key.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key
        /// whose value to get or set.</param>
        /// <value>The <see cref="String"/> value associated with the specified
        /// <paramref name="key"/>. If the specified <paramref name="key"/> is not found,
        /// attempting to get it returns
        /// a null reference,
        /// and attempting to set it creates a new element using the specified
        /// <paramref name="key"/>.</value>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The property is set and the
        /// <see cref="IStringStringDictionary"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The property is set, <paramref name="key"/> does not exist in the collection,
        /// and the <b>IStringStringDictionary</b> has a fixed size.</para>
        /// </exception>
        /// <remarks>Please refer to <see cref="IDictionary.this"/> for details.</remarks>

        String this[String key] { get; set; }

        #endregion
        #region Keys

        /// <summary>
        /// Gets an <see cref="IStringCollection"/> containing the keys
        /// in the <see cref="IStringStringDictionary"/>.
        /// </summary>
        /// <value>An <see cref="IStringCollection"/> containing the keys
        /// in the <see cref="IStringStringDictionary"/>.</value>
        /// <remarks>Please refer to <see cref="IDictionary.Keys"/> for details.</remarks>

        IStringCollection Keys { get; }

        #endregion
        #region Values

        /// <summary>
        /// Gets an <see cref="IStringCollection"/> containing the values
        /// in the <see cref="IStringStringDictionary"/>.
        /// </summary>
        /// <value>An <see cref="IStringCollection"/> containing the values
        /// in the <see cref="IStringStringDictionary"/>.</value>
        /// <remarks>Please refer to <see cref="IDictionary.Values"/> for details.</remarks>

        IStringCollection Values { get; }

        #endregion
        #endregion
        #region Methods
        #region Add

        /// <summary>
        /// Adds an element with the specified <see cref="String"/>
        /// key and <see cref="String"/> value to the
        /// <see cref="IStringStringDictionary"/>.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key of the element
        /// to add to the <see cref="IStringStringDictionary"/>.</param>
        /// <param name="value">The <see cref="String"/> value of the element
        /// to add to the <see cref="IStringStringDictionary"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <exception cref="ArgumentException">
        /// <para>An element with the specified <paramref name="key"/> already exists
        /// in the <see cref="IStringStringDictionary"/>.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringStringDictionary</b> is set to use the
        /// <see cref="IComparable"/> interface, and <paramref name="key"/> does not
        /// implement the <b>IComparable</b> interface.</para></exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <exception cref="InvalidOperationException">
        /// The comparer throws an exception.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringDictionary"/> is read-only.
        /// </para><para>-or-</para>
        /// <para>The <b>IStringStringDictionary</b> has a fixed size.
        /// </para></exception>
        /// <remarks>Please refer to <see cref="IDictionary.Add"/> for details.</remarks>

        void Add(String key, String value);

        #endregion
        #region Clear

        /// <summary>
        /// Removes all elements from the <see cref="IStringStringDictionary"/>.
        /// </summary>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringDictionary"/> is read-only.
        /// </para><para>-or-</para>
        /// <para>The <b>IStringStringDictionary</b> has a fixed size.
        /// </para></exception>
        /// <remarks>Please refer to <see cref="IDictionary.Clear"/> for details.</remarks>

        void Clear();

        #endregion
        #region Contains

        /// <summary>
        /// Determines whether the <see cref="IStringStringDictionary"/>
        /// contains the specified <see cref="String"/> key.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key to locate
        /// in the <see cref="IStringStringDictionary"/>.</param>
        /// <returns><c>true</c> if the <see cref="IStringStringDictionary"/>
        /// contains an element with the specified <paramref name="key"/>; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <exception cref="InvalidOperationException">
        /// The comparer throws an exception.</exception>
        /// <remarks>Please refer to <see cref="IDictionary.Contains"/> for details.</remarks>

        bool Contains(String key);

        #endregion
        #region Remove

        /// <summary>
        /// Removes the element with the specified <see cref="String"/> key
        /// from the <see cref="IStringStringDictionary"/>.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key of the element to remove
        /// from the <see cref="IStringStringDictionary"/>.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <exception cref="InvalidOperationException">
        /// The comparer throws an exception.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringDictionary"/> is read-only.
        /// </para><para>-or-</para>
        /// <para>The <b>IStringStringDictionary</b> has a fixed size.
        /// </para></exception>
        /// <remarks>Please refer to <see cref="IDictionary.Remove"/> for details.</remarks>

        void Remove(String key);

        #endregion
        #endregion
    }

    #endregion
    #region Interface IStringStringList

    /// <summary>
    /// Represents a strongly typed collection of <see cref="NameValueEntry"/>
    /// objects that can be individually accessed by index.
    /// </summary>
    /// <remarks>
    /// <b>IStringStringList</b> provides an <see cref="IList"/>
    /// that is strongly typed for <see cref="NameValueEntry"/> elements.
    /// </remarks>

    public interface
        IStringStringList : IStringStringCollection
    {
        #region Properties
        #region IsFixedSize

        /// <summary>
        /// Gets a value indicating whether the
        /// <see cref="IStringStringList"/> has a fixed size.
        /// </summary>
        /// <value><c>true</c> if the <see cref="IStringStringList"/>
        /// has a fixed size; otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="IList.IsFixedSize"/> for details.</remarks>

        bool IsFixedSize { get; }

        #endregion
        #region IsReadOnly

        /// <summary>
        /// Gets a value indicating whether the
        /// <see cref="IStringStringList"/> is read-only.
        /// </summary>
        /// <value><c>true</c> if the <see cref="IStringStringList"/>
        /// is read-only; otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="IList.IsReadOnly"/> for details.</remarks>

        bool IsReadOnly { get; }

        #endregion
        #region Item

        /// <summary>
        /// Gets or sets the <see cref="NameValueEntry"/> element at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the
        /// <see cref="NameValueEntry"/> element to get or set.</param>
        /// <value>
        /// The <see cref="NameValueEntry"/> element at the specified <paramref name="index"/>.
        /// </value>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than
        /// <see cref="IStringStringCollection.Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">The property is set and the
        /// <see cref="IStringStringList"/> is read-only.</exception>
        /// <remarks>Please refer to <see cref="IList.this"/> for details.</remarks>

        NameValueEntry this[int index] { get; set; }

        #endregion
        #endregion
        #region Methods
        #region Add

        /// <summary>
        /// Adds a <see cref="NameValueEntry"/> to the end
        /// of the <see cref="IStringStringList"/>.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to be added to the end of the <see cref="IStringStringList"/>.
        /// </param>
        /// <returns>The <see cref="IStringStringList"/> index at which
        /// the <paramref name="entry"/> has been added.</returns>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringStringList</b> has a fixed size.</para>
        /// </exception>
        /// <remarks>Please refer to <see cref="IList.Add"/> for details.</remarks>

        int Add(NameValueEntry entry);

        #endregion
        #region Clear

        /// <summary>
        /// Removes all elements from the <see cref="IStringStringList"/>.
        /// </summary>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringStringList</b> has a fixed size.</para>
        /// </exception>
        /// <remarks>Please refer to <see cref="IList.Clear"/> for details.</remarks>

        void Clear();

        #endregion
        #region Contains

        /// <summary>
        /// Determines whether the <see cref="IStringStringList"/>
        /// contains the specified <see cref="NameValueEntry"/> element.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to locate in the <see cref="IStringStringList"/>.</param>
        /// <returns><c>true</c> if <paramref name="entry"/> is found in the
        /// <see cref="IStringStringList"/>; otherwise, <c>false</c>.</returns>
        /// <remarks>Please refer to <see cref="IList.Contains"/> for details.</remarks>

        bool Contains(NameValueEntry entry);

        #endregion
        #region IndexOf

        /// <summary>
        /// Returns the zero-based index of the first occurrence of the specified
        /// <see cref="NameValueEntry"/> in the <see cref="IStringStringList"/>.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to locate in the <see cref="IStringStringList"/>.</param>
        /// <returns>
        /// The zero-based index of the first occurrence of <paramref name="entry"/>
        /// in the <see cref="IStringStringList"/>, if found; otherwise, -1.
        /// </returns>
        /// <remarks>Please refer to <see cref="IList.IndexOf"/> for details.</remarks>

        int IndexOf(NameValueEntry entry);

        #endregion
        #region Insert

        /// <summary>
        /// Inserts a <see cref="NameValueEntry"/> element into the
        /// <see cref="IStringStringList"/> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which
        /// <paramref name="entry"/> should be inserted.</param>
        /// <param name="entry">The <see cref="NameValueEntry"/> object to insert
        /// into the <see cref="IStringStringList"/>.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is greater than
        /// <see cref="IStringStringCollection.Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.Insert"/> for details.</remarks>

        void Insert(int index, NameValueEntry entry);

        #endregion
        #region Remove

        /// <summary>
        /// Removes the first occurrence of the specified <see cref="NameValueEntry"/>
        /// from the <see cref="IStringStringList"/>.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object to remove
        /// from the <see cref="IStringStringList"/>.</param>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.Remove"/> for details.</remarks>

        void Remove(NameValueEntry entry);

        #endregion
        #region RemoveAt

        /// <summary>
        /// Removes the element at the specified index of the
        /// <see cref="IStringStringList"/>.
        /// </summary>
        /// <param name="index">The zero-based index of the element to remove.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than
        /// <see cref="IStringStringCollection.Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="IStringStringList"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>IStringStringList</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="IList.RemoveAt"/> for details.</remarks>

        void RemoveAt(int index);

        #endregion
        #endregion
    }

    #endregion
    #region Interface IStringStringEnumerator

    /// <summary>
    /// Supports type-safe iteration over a dictionary that
    /// contains <see cref="NameValueEntry"/> elements.
    /// </summary>
    /// <remarks>
    /// <b>IStringStringEnumerator</b> provides an
    /// <see cref="IDictionaryEnumerator"/> that is strongly typed for
    /// <see cref="String"/> keys and <see cref="String"/> values.
    /// </remarks>

    public interface IStringStringEnumerator
    {
        #region Properties
        #region Current

        /// <summary>
        /// Gets the current <see cref="NameValueEntry"/> element in the collection.
        /// </summary>
        /// <value>The current <see cref="NameValueEntry"/> element in the collection.</value>
        /// <exception cref="InvalidOperationException"><para>The enumerator is positioned
        /// before the first element of the collection or after the last element.</para>
        /// <para>-or-</para>
        /// <para>The collection was modified after the enumerator was created.</para></exception>
        /// <remarks>Please refer to <see cref="IEnumerator.Current"/> for details, but note
        /// that <b>Current</b> fails if the collection was modified since the last successful
        /// call to <see cref="MoveNext"/> or <see cref="Reset"/>.</remarks>

        NameValueEntry Current { get; }

        #endregion
        #region Entry

        /// <summary>
        /// Gets a <see cref="NameValueEntry"/> containing both
        /// the key and the value of the current dictionary entry.
        /// </summary>
        /// <value>A <see cref="NameValueEntry"/> containing both
        /// the key and the value of the current dictionary entry.</value>
        /// <exception cref="InvalidOperationException"><para>The enumerator is positioned
        /// before the first element of the dictionary or after the last element.</para>
        /// <para>-or-</para>
        /// <para>The dictionary was modified after the enumerator was created.</para></exception>
        /// <remarks>Please refer to <see cref="IDictionaryEnumerator.Entry"/> for details, but
        /// note that <b>Entry</b> fails if the collection was modified since the last successful
        /// call to <see cref="MoveNext"/> or <see cref="Reset"/>.</remarks>

        NameValueEntry Entry { get; }

        #endregion
        #region Key

        /// <summary>
        /// Gets the <see cref="String"/> key of the current dictionary entry.
        /// </summary>
        /// <value>The <see cref="String"/> key
        /// of the current element of the enumeration.</value>
        /// <exception cref="InvalidOperationException"><para>The enumerator is positioned
        /// before the first element of the dictionary or after the last element.</para>
        /// <para>-or-</para>
        /// <para>The dictionary was modified after the enumerator was created.</para></exception>
        /// <remarks>Please refer to <see cref="IDictionaryEnumerator.Key"/> for details, but
        /// note that <b>Key</b> fails if the collection was modified since the last successful
        /// call to <see cref="MoveNext"/> or <see cref="Reset"/>.</remarks>

        String Key { get; }

        #endregion
        #region Value

        /// <summary>
        /// Gets the <see cref="String"/> value of the current dictionary entry.
        /// </summary>
        /// <value>The <see cref="String"/> value
        /// of the current element of the enumeration.</value>
        /// <exception cref="InvalidOperationException"><para>The enumerator is positioned
        /// before the first element of the dictionary or after the last element.</para>
        /// <para>-or-</para>
        /// <para>The dictionary was modified after the enumerator was created.</para></exception>
        /// <remarks>Please refer to <see cref="IDictionaryEnumerator.Value"/> for details, but
        /// note that <b>Value</b> fails if the collection was modified since the last successful
        /// call to <see cref="MoveNext"/> or <see cref="Reset"/>.</remarks>

        String Value { get; }

        #endregion
        #endregion
        #region Methods
        #region MoveNext

        /// <summary>
        /// Advances the enumerator to the next element of the collection.
        /// </summary>
        /// <returns><c>true</c> if the enumerator was successfully advanced to the next element;
        /// <c>false</c> if the enumerator has passed the end of the collection.</returns>
        /// <exception cref="InvalidOperationException">
        /// The collection was modified after the enumerator was created.</exception>
        /// <remarks>Please refer to <see cref="IEnumerator.MoveNext"/> for details.</remarks>

        bool MoveNext();

        #endregion
        #region Reset

        /// <summary>
        /// Sets the enumerator to its initial position,
        /// which is before the first element in the collection.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// The collection was modified after the enumerator was created.</exception>
        /// <remarks>Please refer to <see cref="IEnumerator.Reset"/> for details.</remarks>

        void Reset();

        #endregion
        #endregion
    }

    #endregion
    #region Struct NameValueEntry

    /// <summary>
    /// Implements a strongly typed pair of one <see cref="String"/>
    /// key and one <see cref="String"/> value.
    /// </summary>
    /// <remarks>
    /// <b>NameValueEntry</b> provides a <see cref="DictionaryEntry"/> that is strongly
    /// typed for <see cref="String"/> keys and <see cref="String"/> values.
    /// </remarks>

    [Serializable]
    public struct NameValueEntry
    {
        #region Private Fields

        private String _key;
        private String _value;

        #endregion
        #region Public Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="NameValueEntry"/>
        /// class with the specified key and value.
        /// </summary>
        /// <param name="key">
        /// The <see cref="String"/> key in the key-and-value pair.</param>
        /// <param name="value">
        /// The <see cref="String"/> value in the key-and-value pair.
        /// This argument can be a null reference.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>

        public NameValueEntry(String key, String value)
        {
            if ((object)key == null)
                throw new ArgumentNullException("key");

            this._key = key;
            this._value = value;
        }

        #endregion
        #region Public Properties
        #region Key

        /// <summary>
        /// Gets or sets the <see cref="String"/> key in the key-and-value pair.
        /// </summary>
        /// <value>
        /// The <see cref="String"/> key in the key-and-value pair.
        /// The default is a null reference.
        /// </value>
        /// <exception cref="ArgumentNullException">
        /// <b>Key</b> is set to a null reference.</exception>
        /// <remarks>
        /// <see cref="NameValueEntry"/> is a value type and therefore has an implicit default
        /// constructor that zeroes all data members. This means that the <b>Key</b> property of
        /// a default-constructed <b>NameValueEntry</b> contains a null reference by default,
        /// even though it is not possible to explicitly set <b>Key</b> to a null reference.
        /// </remarks>

        [XmlAttribute("key")]
        public String Key
        {
            get { return this._key; }
            set
            {
                if ((object)value == null)
                    throw new ArgumentNullException("value");
                this._key = value;
            }
        }

        #endregion
        #region Value

        /// <summary>
        /// Gets or sets the <see cref="String"/> value in the key-and-value pair.
        /// </summary>
        /// <value>
        /// The <see cref="String"/> value in the key-and-value pair.
        /// This value can be a null reference, which is also the default.
        /// </value>

        [XmlText()]
        public String Value
        {
            get { return this._value; }
            set { this._value = value; }
        }

        #endregion
        #endregion
        #region Public Operators
        #region NameValueEntry(DictionaryEntry)

        /// <summary>
        /// Converts a <see cref="DictionaryEntry"/> to a <see cref="NameValueEntry"/>.
        /// </summary>
        /// <param name="entry">A <see cref="DictionaryEntry"/> object to convert.</param>
        /// <returns>A <see cref="NameValueEntry"/> object that represents
        /// the converted <paramref name="entry"/>.</returns>
        /// <exception cref="InvalidCastException">
        /// <para><paramref name="entry"/> contains a key that is not compatible
        /// with <see cref="String"/>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="entry"/> contains a value that is not compatible
        /// with <see cref="String"/>.</para>
        /// </exception>

        public static implicit operator NameValueEntry(DictionaryEntry entry)
        {
            NameValueEntry pair = new NameValueEntry();
            if (entry.Key != null) pair.Key = (String)entry.Key;
            if (entry.Value != null) pair.Value = (String)entry.Value;
            return pair;
        }

        #endregion
        #region DictionaryEntry(NameValueEntry)

        /// <summary>
        /// Converts a <see cref="NameValueEntry"/> to a <see cref="DictionaryEntry"/>.
        /// </summary>
        /// <param name="pair">A <see cref="NameValueEntry"/> object to convert.</param>
        /// <returns>A <see cref="DictionaryEntry"/> object that
        /// represents the converted <paramref name="pair"/>.</returns>

        public static implicit operator DictionaryEntry(NameValueEntry pair)
        {
            DictionaryEntry entry = new DictionaryEntry();
            if (pair.Key != null) entry.Key = pair.Key;
            entry.Value = pair.Value;
            return entry;
        }

        #endregion
        #endregion
    }

    #endregion
    #region Class NameValueCollection

    /// <summary>
    /// Implements a strongly typed collection of <see cref="NameValueEntry"/> key-and-value
    /// pairs that retain their insertion order and are accessible by index and by key.
    /// </summary>
    /// <remarks><para>
    /// <b>NameValueCollection</b> provides an <see cref="ArrayList"/> that is strongly
    /// typed for <see cref="NameValueEntry"/> elements and allows direct access to
    /// its <see cref="String"/> keys and <see cref="String"/> values.
    /// </para><para>
    /// The collection may contain multiple identical keys. All key access methods return the
    /// first occurrence of the specified key, if found. Access by index is an O(1) operation
    /// but access by key or value are both O(<em>N</em>) operations, where <em>N</em> is the
    /// current value of the <see cref="NameValueCollection.Count"/> property.
    /// </para></remarks>

    [Serializable]
    [TypeConverter(typeof(NameValueCollectionTypeConverter))]
    [Editor(typeof(NameValueCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
    public class NameValueCollection :
        IStringStringList, IList, ICloneable
    {
        #region Private Fields

        private const int _defaultCapacity = 16;

        private String[] _keys;
        private String[] _values;
        private int _count;

        [NonSerialized]
        private int _version;
        private KeyList _keyList;
        private ValueList _valueList;

        #endregion
        #region Private Constructors

        // helper type to identify private ctor
        private enum Tag { Default }

        private NameValueCollection(Tag tag) { }

        #endregion
        #region Public Constructors
        #region NameValueCollection()

        /// <overloads>
        /// Initializes a new instance of the <see cref="NameValueCollection"/> class.
        /// </overloads>
        /// <summary>
        /// Initializes a new instance of the <see cref="NameValueCollection"/> class
        /// that is empty and has the default initial capacity.
        /// </summary>
        /// <remarks>Please refer to <see cref="ArrayList()"/> for details.</remarks>

        public NameValueCollection()
        {
            this._keys = new String[_defaultCapacity];
            this._values = new String[_defaultCapacity];
        }

        #endregion
        #region NameValueCollection(Int32)

        /// <summary>
        /// Initializes a new instance of the <see cref="NameValueCollection"/> class
        /// that is empty and has the specified initial capacity.
        /// </summary>
        /// <param name="capacity">The number of elements that the new
        /// <see cref="NameValueCollection"/> is initially capable of storing.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="capacity"/> is less than zero.</exception>
        /// <remarks>Please refer to <see cref="ArrayList(Int32)"/> for details.</remarks>

        public NameValueCollection(int capacity)
        {
            if (capacity < 0)
                throw new ArgumentOutOfRangeException("capacity",
                    capacity, "Argument cannot be negative.");

            this._keys = new String[capacity];
            this._values = new String[capacity];
        }

        #endregion
        #region NameValueCollection(NameValueCollection)

        /// <summary>
        /// Initializes a new instance of the <see cref="NameValueCollection"/> class
        /// that contains elements copied from the specified collection and
        /// that has the same initial capacity as the number of elements copied.
        /// </summary>
        /// <param name="collection">The <see cref="NameValueCollection"/>
        /// whose elements are copied to the new collection.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>
        /// <remarks>Please refer to <see cref="ArrayList(ICollection)"/> for details.</remarks>

        public NameValueCollection(NameValueCollection collection)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");

            this._keys = new String[collection.Count];
            this._values = new String[collection.Count];
            AddRange(collection);
        }

        #endregion
        #region NameValueCollection(NameValueEntry[])

        /// <summary>
        /// Initializes a new instance of the <see cref="NameValueCollection"/> class
        /// that contains elements copied from the specified <see cref="NameValueEntry"/>
        /// array and that has the same initial capacity as the number of elements copied.
        /// </summary>
        /// <param name="array">An <see cref="Array"/> of <see cref="NameValueEntry"/>
        /// elements that are copied to the new collection.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="array"/> is a null reference.</exception>
        /// <remarks>Please refer to <see cref="ArrayList(ICollection)"/> for details.</remarks>

        public NameValueCollection(NameValueEntry[] array)
        {
            if (array == null)
                throw new ArgumentNullException("array");

            this._keys = new String[array.Length];
            this._values = new String[array.Length];
            AddRange(array);
        }

        #endregion
        #endregion
        #region Protected Properties
        #region InnerKeys

        /// <summary>
        /// Gets the list of keys contained in the <see cref="NameValueCollection"/> instance.
        /// </summary>
        /// <value>
        /// A one-dimensional <see cref="Array"/> with zero-based indexing that contains all 
        /// <see cref="String"/> elements in the <see cref="NameValueCollection"/>.
        /// </value>
        /// <remarks>
        /// Use <b>InnerKeys</b> to access the key array of a <see cref="NameValueCollection"/>
        /// instance that might be a read-only or synchronized wrapper. This is necessary 
        /// because the key and value arrays of wrapper classes are always null references.
        /// </remarks>

        protected virtual String[] InnerKeys
        {
            get { return this._keys; }
        }

        #endregion
        #region InnerValues

        /// <summary>
        /// Gets the list of values contained in the <see cref="NameValueCollection"/> instance.
        /// </summary>
        /// <value>
        /// A one-dimensional <see cref="Array"/> with zero-based indexing that contains all 
        /// <see cref="String"/> elements in the <see cref="NameValueCollection"/>.
        /// </value>
        /// <remarks>
        /// Use <b>InnerValues</b> to access the value array of a <see cref="NameValueCollection"/>
        /// instance that might be a read-only or synchronized wrapper. This is necessary
        /// because the key and value arrays of wrapper classes are always null references.
        /// </remarks>

        protected virtual String[] InnerValues
        {
            get { return this._values; }
        }

        #endregion
        #endregion
        #region Public Properties
        #region Capacity

        /// <summary>
        /// Gets or sets the capacity of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <value>The number of elements that the
        /// <see cref="NameValueCollection"/> can contain.</value>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <b>Capacity</b> is set to a value that is less than <see cref="Count"/>.</exception>
        /// <remarks>Please refer to <see cref="ArrayList.Capacity"/> for details.</remarks>

        public virtual int Capacity
        {
            get { return this._keys.Length; }
            set
            {
                if (value == this._keys.Length) return;

                if (value < this._count)
                    throw new ArgumentOutOfRangeException("Capacity",
                        value, "Value cannot be less than Count.");

                if (value == 0)
                {
                    this._keys = new String[_defaultCapacity];
                    this._values = new String[_defaultCapacity];
                    return;
                }

                String[] newKeys = new String[value];
                String[] newValues = new String[value];

                Array.Copy(this._keys, 0, newKeys, 0, this._count);
                Array.Copy(this._values, 0, newValues, 0, this._count);

                this._keys = newKeys;
                this._values = newValues;
            }
        }

        #endregion
        #region Count

        /// <summary>
        /// Gets the number of key-and-value pairs contained
        /// in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <value>The number of key-and-value pairs contained
        /// in the <see cref="NameValueCollection"/>.</value>
        /// <remarks>Please refer to <see cref="ArrayList.Count"/> for details.</remarks>

        public virtual int Count
        {
            get { return this._count; }
        }

        #endregion
        #region IsFixedSize

        /// <summary>
        /// Gets a value indicating whether the <see cref="NameValueCollection"/> has a fixed size.
        /// </summary>
        /// <value><c>true</c> if the <see cref="NameValueCollection"/> has a fixed size;
        /// otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="ArrayList.IsFixedSize"/> for details.</remarks>

        public virtual bool IsFixedSize
        {
            get { return false; }
        }

        #endregion
        #region IsReadOnly

        /// <summary>
        /// Gets a value indicating whether the <see cref="NameValueCollection"/> is read-only.
        /// </summary>
        /// <value><c>true</c> if the <see cref="NameValueCollection"/> is read-only;
        /// otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="ArrayList.IsReadOnly"/> for details.</remarks>

        public virtual bool IsReadOnly
        {
            get { return false; }
        }

        #endregion
        #region IsSynchronized

        /// <summary>
        /// Gets a value indicating whether access to the <see cref="NameValueCollection"/>
        /// is synchronized (thread-safe).
        /// </summary>
        /// <value><c>true</c> if access to the <see cref="NameValueCollection"/> is
        /// synchronized (thread-safe); otherwise, <c>false</c>. The default is <c>false</c>.</value>
        /// <remarks>Please refer to <see cref="ArrayList.IsSynchronized"/> for details.</remarks>

        public virtual bool IsSynchronized
        {
            get { return false; }
        }

        #endregion
        #region Item: NameValueEntry

        /// <summary>
        /// Gets or sets the <see cref="NameValueEntry"/> element at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the
        /// <see cref="NameValueEntry"/> element to get or set.</param>
        /// <value>
        /// The <see cref="NameValueEntry"/> element at the specified <paramref name="index"/>.
        /// </value>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// The property is set and the <see cref="NameValueCollection"/> is read-only.</exception>
        /// <remarks>Please refer to <see cref="ArrayList.this"/> for details.</remarks>

        public virtual NameValueEntry this[int index]
        {
            get
            {
                ValidateIndex(index);
                return new NameValueEntry(this._keys[index], this._values[index]);
            }
            set
            {
                ValidateIndex(index);
                ++this._version;
                this._keys[index] = value.Key;
                this._values[index] = value.Value;
            }
        }

        #endregion
        #region IList.Item: Object

        /// <summary>
        /// Gets or sets the element at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the element to get or set.</param>
        /// <value>
        /// The element at the specified <paramref name="index"/>, returned as a boxed
        /// <see cref="DictionaryEntry"/> value. When the property is set, this value 
        /// must be compatible with <see cref="NameValueEntry"/>.
        /// </value>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <exception cref="InvalidCastException">The property is set to a value
        /// that is not compatible with <see cref="NameValueEntry"/>.</exception>
        /// <exception cref="NotSupportedException">
        /// The property is set and the <see cref="NameValueCollection"/> is read-only.</exception>
        /// <remarks>Please refer to <see cref="ArrayList.this"/> for details.</remarks>

        object IList.this[int index]
        {
            get { return (DictionaryEntry)this[index]; }
            set { this[index] = (NameValueEntry)(DictionaryEntry)value; }
        }

        #endregion
        #region Keys

        /// <summary>
        /// Gets an <see cref="IStringCollection"/> containing
        /// the keys in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <value>An <see cref="IStringCollection"/> containing
        /// the keys in the <see cref="NameValueCollection"/>.</value>
        /// <remarks>Please refer to <see cref="SortedList.Keys"/> for details.</remarks>

        public virtual IStringCollection Keys
        {
            get { return GetKeyList(); }
        }

        #endregion
        #region SyncRoot

        /// <summary>
        /// Gets an object that can be used to synchronize
        /// access to the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <value>An object that can be used to synchronize
        /// access to the <see cref="NameValueCollection"/>.</value>
        /// <remarks>Please refer to <see cref="SortedList.SyncRoot"/> for details.</remarks>

        public virtual object SyncRoot
        {
            get { return this; }
        }

        #endregion
        #region Values

        /// <summary>
        /// Gets an <see cref="IStringCollection"/> containing
        /// the values in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <value>An <see cref="IStringCollection"/> containing
        /// the values in the <see cref="NameValueCollection"/>.</value>
        /// <remarks>Please refer to <see cref="SortedList.Values"/> for details.</remarks>

        public virtual IStringCollection Values
        {
            get { return GetValueList(); }
        }

        #endregion
        #endregion
        #region Public Methods
        #region Add(NameValueEntry)

        /// <overloads>
        /// Adds an element to the end of the <see cref="NameValueCollection"/>.
        /// </overloads>
        /// <summary>
        /// Adds a <see cref="NameValueEntry"/> to the end of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to be added to the end of the <see cref="NameValueCollection"/>.</param>
        /// <returns>The <see cref="NameValueCollection"/> index at which the
        /// <paramref name="entry"/> has been added.</returns>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.Add"/> for details.</remarks>

        public virtual int Add(NameValueEntry entry)
        {
            if (this._count == this._keys.Length)
                EnsureCapacity(this._count + 1);

            ++this._version;
            this._keys[this._count] = entry.Key;
            this._values[this._count] = entry.Value;
            return this._count++;
        }

        #endregion
        #region Add(String, String)

        /// <summary>
        /// Adds an element with the specified <see cref="String"/> key and
        /// <see cref="String"/> value to the end of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key of the element
        /// to add to the end of the <see cref="NameValueCollection"/>.</param>
        /// <param name="value">The <see cref="String"/> value of the element
        /// to add to the end of the <see cref="NameValueCollection"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <returns>The <see cref="NameValueCollection"/> index at which the
        /// new element has been added.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="SortedList.Add"/> for details but note that
        /// the <see cref="NameValueCollection"/> may contain multiple identical keys.</remarks>

        public int Add(String key, String value)
        {
            if ((object)key == null)
                throw new ArgumentNullException("key");

            return Add(new NameValueEntry(key, value));
        }

        #endregion
        #region IList.Add(Object)

        /// <summary>
        /// Adds an <see cref="Object"/> to the end of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="entry">
        /// The object to be added to the end of the <see cref="NameValueCollection"/>.
        /// This argument must be compatible with <see cref="NameValueEntry"/>.</param>
        /// <returns>The <see cref="NameValueCollection"/> index at which the
        /// <paramref name="entry"/> has been added.</returns>
        /// <exception cref="InvalidCastException"><paramref name="entry"/>
        /// is not compatible with <see cref="NameValueEntry"/>.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.Add"/> for details.</remarks>

        int IList.Add(object entry)
        {
            return Add((NameValueEntry)entry);
        }

        #endregion
        #region AddRange(NameValueCollection)

        /// <overloads>
        /// Adds a range of elements to the end of the <see cref="NameValueCollection"/>.
        /// </overloads>
        /// <summary>
        /// Adds the elements of another collection to the end of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="collection">The <see cref="NameValueCollection"/> whose elements
        /// should be added to the end of the current collection.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.AddRange"/> for details.</remarks>

        public virtual void AddRange(NameValueCollection collection)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");

            if (collection.Count == 0) return;
            if (this._count + collection.Count > this._keys.Length)
                EnsureCapacity(this._count + collection.Count);

            ++this._version;
            Array.Copy(collection.InnerKeys, 0, this._keys, this._count, collection.Count);
            Array.Copy(collection.InnerValues, 0, this._values, this._count, collection.Count);
            this._count += collection.Count;
        }

        #endregion
        #region AddRange(NameValueEntry[])

        /// <summary>
        /// Adds the elements of a <see cref="NameValueEntry"/> array
        /// to the end of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="array">An <see cref="Array"/> of <see cref="NameValueEntry"/> elements
        /// that should be added to the end of the <see cref="NameValueCollection"/>.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="array"/> is a null reference.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.AddRange"/> for details.</remarks>

        public virtual void AddRange(NameValueEntry[] array)
        {
            if (array == null)
                throw new ArgumentNullException("array");

            if (array.Length == 0) return;
            if (this._count + array.Length > this._keys.Length)
                EnsureCapacity(this._count + array.Length);

            ++this._version;
            for (int i = 0; i < array.Length; ++i, ++this._count)
            {
                this._keys[this._count] = array[i].Key;
                this._values[this._count] = array[i].Value;
            }
        }

        #endregion
        #region Clear

        /// <summary>
        /// Removes all elements from the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.Clear"/> for details.</remarks>

        public virtual void Clear()
        {
            if (this._count == 0) return;

            ++this._version;
            Array.Clear(this._keys, 0, this._count);
            Array.Clear(this._values, 0, this._count);
            this._count = 0;
        }

        #endregion
        #region Clone

        /// <summary>
        /// Creates a shallow copy of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <returns>A shallow copy of the <see cref="NameValueCollection"/>.</returns>
        /// <remarks>Please refer to <see cref="ArrayList.Clone"/> for details.</remarks>

        public virtual object Clone()
        {
            NameValueCollection collection = new NameValueCollection(this._count);

            Array.Copy(this._keys, 0, collection._keys, 0, this._count);
            Array.Copy(this._values, 0, collection._values, 0, this._count);

            collection._count = this._count;
            collection._version = this._version;

            return collection;
        }

        #endregion
        #region Contains(NameValueEntry)

        /// <summary>
        /// Determines whether the <see cref="NameValueCollection"/>
        /// contains the specified <see cref="NameValueEntry"/> element.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to locate in the <see cref="NameValueCollection"/>.</param>
        /// <returns><c>true</c> if <paramref name="entry"/> is found in the
        /// <see cref="NameValueCollection"/>; otherwise, <c>false</c>.</returns>
        /// <remarks><para>
        /// Please refer to <see cref="ArrayList.Contains"/> for details.
        /// </para><para>
        /// <b>Contains</b> uses the equality operators defined by <see cref="String"/>
        /// and <see cref="String"/> to locate the specified <paramref name="entry"/>.
        /// </para></remarks>

        public bool Contains(NameValueEntry entry)
        {
            return (IndexOf(entry) >= 0);
        }

        #endregion
        #region IList.Contains(Object)

        /// <summary>
        /// Determines whether the <see cref="NameValueCollection"/> contains the specified element.
        /// </summary>
        /// <param name="entry">The object to locate in the <see cref="NameValueCollection"/>.
        /// This argument must be compatible with <see cref="NameValueEntry"/>.</param>
        /// <returns><c>true</c> if <paramref name="entry"/> is found in the
        /// <see cref="NameValueCollection"/>; otherwise, <c>false</c>.</returns>
        /// <exception cref="InvalidCastException"><paramref name="entry"/>
        /// is not compatible with <see cref="NameValueEntry"/>.</exception>
        /// <remarks>Please refer to <see cref="ArrayList.Contains"/> for details.</remarks>

        bool IList.Contains(object entry)
        {
            return Contains((NameValueEntry)entry);
        }

        #endregion
        #region ContainsKey

        /// <summary>
        /// Determines whether the <see cref="NameValueCollection"/>
        /// contains the specified <see cref="String"/> key.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key
        /// to locate in the <see cref="NameValueCollection"/>.</param>
        /// <returns><c>true</c> if the <see cref="NameValueCollection"/> contains an element
        /// with the specified <paramref name="key"/>; otherwise, <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <remarks>Please refer to <see cref="SortedList.ContainsKey"/> for details but note
        /// that the <see cref="NameValueCollection"/> requires linear time to locate a key.</remarks>

        public bool ContainsKey(String key)
        {
            return (IndexOfKey(key) >= 0);
        }

        #endregion
        #region ContainsValue

        /// <summary>
        /// Determines whether the <see cref="NameValueCollection"/>
        /// contains the specified <see cref="String"/> value.
        /// </summary>
        /// <param name="value">The <see cref="String"/> value
        /// to locate in the <see cref="NameValueCollection"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <returns><c>true</c> if the <see cref="NameValueCollection"/> contains an element
        /// with the specified <paramref name="value"/>; otherwise, <c>false</c>.</returns>
        /// <remarks>Please refer to <see cref="SortedList.ContainsValue"/> for details.</remarks>

        public bool ContainsValue(String value)
        {
            return (IndexOfValue(value) >= 0);
        }

        #endregion
        #region CopyTo(NameValueEntry[], Int32)

        /// <summary>
        /// Copies the entire <see cref="NameValueCollection"/> to a one-dimensional <see cref="Array"/> of
        /// <see cref="NameValueEntry"/> elements, starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the
        /// <see cref="NameValueEntry"/> elements copied from the <see cref="NameValueCollection"/>.
        /// The <b>Array</b> must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in <paramref name="array"/>
        /// at which copying begins.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="array"/> is a null reference.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="arrayIndex"/> is less than zero.</exception>
        /// <exception cref="ArgumentException"><para>
        /// <paramref name="arrayIndex"/> is equal to or greater than the length of <paramref name="array"/>.
        /// </para><para>-or-</para><para>
        /// The number of elements in the source <see cref="NameValueCollection"/> is greater than
        /// the available space from <paramref name="arrayIndex"/> to the end of the destination
        /// <paramref name="array"/>.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.CopyTo"/> for details.</remarks>

        public virtual void CopyTo(NameValueEntry[] array, int arrayIndex)
        {
            CheckTargetArray(array, arrayIndex);

            for (int i = 0; i < this._count; i++)
                array[arrayIndex + i] =
                    new NameValueEntry(this._keys[i], this._values[i]);
        }

        #endregion
        #region ICollection.CopyTo(Array, Int32)

        /// <summary>
        /// Copies the entire <see cref="NameValueCollection"/> to a one-dimensional <see cref="Array"/>,
        /// starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the
        /// <see cref="NameValueEntry"/> elements copied from the <see cref="NameValueCollection"/>.
        /// The <b>Array</b> must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in <paramref name="array"/>
        /// at which copying begins.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="array"/> is a null reference.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="arrayIndex"/> is less than zero.</exception>
        /// <exception cref="ArgumentException"><para>
        /// <paramref name="array"/> is multidimensional.
        /// </para><para>-or-</para><para>
        /// <paramref name="arrayIndex"/> is equal to or greater than the length of <paramref name="array"/>.
        /// </para><para>-or-</para><para>
        /// The number of elements in the source <see cref="NameValueCollection"/> is greater than
        /// the available space from <paramref name="arrayIndex"/> to the end of the destination
        /// <paramref name="array"/>.</para></exception>
        /// <exception cref="InvalidCastException">
        /// The <see cref="NameValueEntry"/> type cannot be cast automatically
        /// to the type of the destination <paramref name="array"/>.</exception>
        /// <remarks>Please refer to <see cref="ArrayList.CopyTo"/> for details.</remarks>

        void ICollection.CopyTo(Array array, int arrayIndex)
        {
            CheckTargetArray(array, arrayIndex);
            CopyTo((NameValueEntry[])array, arrayIndex);
        }

        #endregion
        #region Equals

        /// <summary>
        /// Determines whether the specified <see cref="NameValueCollection"/>
        /// is equal to the current <b>NameValueCollection</b>.
        /// </summary>
        /// <param name="collection">The <see cref="NameValueCollection"/>
        /// to compare with the current <b>NameValueCollection</b>.</param>
        /// <returns><c>true</c> if the specified <see cref="NameValueCollection"/> is equal
        /// to the current <b>NameValueCollection</b>; otherwise, <c>false</c>.</returns>
        /// <remarks><para>
        /// This <b>Equals</b> overload tests for value equality of all <see cref="NameValueEntry"/>
        /// elements contained in the two <see cref="NameValueCollection"/> collections.
        /// </para><para>
        /// <b>Equals</b> returns <c>false</c> if <paramref name="collection"/> is a null
        /// reference, holds a different number of elements, or holds at least one
        /// <see cref="NameValueEntry"/> element at a given index position whose key and/or
        /// value is different from that of the element at the same index position in this
        /// <b>NameValueCollection</b>, as determined by the inequality operators defined by
        /// <see cref="String"/> and <see cref="String"/>.
        /// </para></remarks>

        public virtual bool Equals(NameValueCollection collection)
        {
            if (collection == null || this._count != collection.Count)
                return false;

            for (int i = 0; i < this._count; i++)
                if (this._keys[i] != collection.InnerKeys[i] ||
                    this._values[i] != collection.InnerValues[i])
                    return false;

            return true;
        }

        #endregion
        #region GetByIndex

        /// <summary>
        /// Gets the <see cref="String"/> value at the
        /// specified index of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="index">The zero-based index of the
        /// <see cref="String"/> value to get.</param>
        /// <returns>The <see cref="String"/> value at the specified
        /// <paramref name="index"/> of the <see cref="NameValueCollection"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <remarks>Please refer to <see cref="SortedList.GetByIndex"/> for details.</remarks>

        public virtual String GetByIndex(int index)
        {
            ValidateIndex(index);
            return this._values[index];
        }

        #endregion
        #region GetByKey

        /// <summary>
        /// Gets the <see cref="String"/> value associated with the
        /// first occurrence of the specified <see cref="String"/> key.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key whose value to get.</param>
        /// <returns>The <see cref="String"/> value associated with the first occurrence
        /// of the specified <paramref name="key"/>, if found; otherwise,
        /// a null reference.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <remarks><b>GetByKey</b> and <see cref="SetByKey"/> emulate the indexer of the
        /// <see cref="SortedList"/> class but require linear time to locate a key.</remarks>

        public virtual String GetByKey(String key)
        {
            int index = IndexOfKey(key);
            if (index >= 0) return this._values[index];
            return null;
        }

        #endregion
        #region GetEnumerator: IStringStringEnumerator

        /// <summary>
        /// Returns an <see cref="IStringStringEnumerator"/> that can
        /// iterate through the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <returns>An <see cref="IStringStringEnumerator"/>
        /// for the entire <see cref="NameValueCollection"/>.</returns>
        /// <remarks>Please refer to <see cref="ArrayList.GetEnumerator"/> for details.</remarks>

        public virtual IStringStringEnumerator GetEnumerator()
        {
            return new Enumerator(this);
        }

        #endregion
        #region IEnumerable.GetEnumerator: IEnumerator

        /// <summary>
        /// Returns an <see cref="IEnumerator"/> that can
        /// iterate through the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <returns>An <see cref="IEnumerator"/>
        /// for the entire <see cref="NameValueCollection"/>.</returns>
        /// <remarks>Please refer to <see cref="ArrayList.GetEnumerator"/> for details.</remarks>

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }

        #endregion
        #region GetKey

        /// <summary>
        /// Gets the <see cref="String"/> key at the
        /// specified index of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="index">The zero-based index of the
        /// <see cref="String"/> key to get.</param>
        /// <returns>The <see cref="String"/> key at the specified
        /// <paramref name="index"/> of the <see cref="NameValueCollection"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <remarks>Please refer to <see cref="SortedList.GetKey"/> for details.</remarks>

        public virtual String GetKey(int index)
        {
            ValidateIndex(index);
            return this._keys[index];
        }

        #endregion
        #region GetKeyList

        /// <summary>
        /// Gets the keys in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <returns>An <see cref="IStringList"/> containing the keys
        /// in the <see cref="NameValueCollection"/>.</returns>
        /// <remarks>Please refer to <see cref="SortedList.GetKeyList"/> for details.</remarks>

        public virtual IStringList GetKeyList()
        {
            if (this._keyList == null)
                this._keyList = new KeyList(this);
            return this._keyList;
        }

        #endregion
        #region GetValueList

        /// <summary>
        /// Gets the values in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <returns>An <see cref="IStringList"/> containing the values
        /// in the <see cref="NameValueCollection"/>.</returns>
        /// <remarks>Please refer to <see cref="SortedList.GetValueList"/> for details.</remarks>

        public virtual IStringList GetValueList()
        {
            if (this._valueList == null)
                this._valueList = new ValueList(this);
            return this._valueList;
        }

        #endregion
        #region IndexOf(NameValueEntry)

        /// <summary>
        /// Returns the zero-based index of the first occurrence of the specified
        /// <see cref="NameValueEntry"/> in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to locate in the <see cref="NameValueCollection"/>.</param>
        /// <returns>
        /// The zero-based index of the first occurrence of <paramref name="entry"/>
        /// in the <see cref="NameValueCollection"/>, if found; otherwise, -1.
        /// </returns>
        /// <remarks><para>
        /// Please refer to <see cref="ArrayList.IndexOf"/> for details.
        /// </para><para>
        /// <b>IndexOf</b> uses the equality operators defined by <see cref="String"/>
        /// and <see cref="String"/> to locate the specified <paramref name="entry"/>.
        /// </para></remarks>

        public virtual int IndexOf(NameValueEntry entry)
        {

            for (int i = 0; i < this._count; ++i)
                if (entry.Key == this._keys[i] &&
                    entry.Value == this._values[i])
                    return i;

            return -1;
        }

        #endregion
        #region IList.IndexOf(Object)

        /// <summary>
        /// Returns the zero-based index of the first occurrence of the specified
        /// <see cref="Object"/> in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="entry">The object to locate in the <see cref="NameValueCollection"/>.
        /// This argument must be compatible with <see cref="NameValueEntry"/>.</param>
        /// <returns>
        /// The zero-based index of the first occurrence of <paramref name="entry"/>
        /// in the <see cref="NameValueCollection"/>, if found; otherwise, -1.
        /// </returns>
        /// <exception cref="InvalidCastException"><paramref name="entry"/>
        /// is not compatible with <see cref="NameValueEntry"/>.</exception>
        /// <remarks>Please refer to <see cref="ArrayList.IndexOf"/> for details.</remarks>

        int IList.IndexOf(object entry)
        {
            return IndexOf((NameValueEntry)entry);
        }

        #endregion
        #region IndexOfKey

        /// <summary>
        /// Returns the zero-based index of the first occurrence of the specified
        /// <see cref="String"/> key in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key
        /// to locate in the <see cref="NameValueCollection"/>.</param>
        /// <returns>
        /// The zero-based index of the first occurrence of <paramref name="key"/>
        /// in the <see cref="NameValueCollection"/>, if found; otherwise, -1.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <remarks>Please refer to <see cref="SortedList.IndexOfKey"/> for details but note
        /// that the <see cref="NameValueCollection"/> requires linear time to locate a key.</remarks>

        public virtual int IndexOfKey(String key)
        {
            if ((object)key == null)
                throw new ArgumentNullException("key");
            return Array.IndexOf(this._keys, key, 0, this._count);
        }

        #endregion
        #region IndexOfValue

        /// <summary>
        /// Returns the zero-based index of first occurrence of the specified
        /// <see cref="String"/> value in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="value">The <see cref="String"/> value
        /// to locate in the <see cref="NameValueCollection"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <returns>
        /// The zero-based index of the first occurrence of <paramref name="value"/>
        /// in the <see cref="NameValueCollection"/>, if found; otherwise, -1.
        /// </returns>
        /// <remarks>Please refer to <see cref="SortedList.IndexOfValue"/> for details.</remarks>

        public virtual int IndexOfValue(String value)
        {
            return Array.IndexOf(this._values, value, 0, this._count);
        }

        #endregion
        #region Insert(Int32, NameValueEntry)

        /// <summary>
        /// Inserts a <see cref="NameValueEntry"/> element into the
        /// <see cref="NameValueCollection"/> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which <paramref name="entry"/>
        /// should be inserted.</param>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to insert into the <see cref="NameValueCollection"/>.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.Insert"/> for details.</remarks>

        public virtual void Insert(int index, NameValueEntry entry)
        {
            if (index < 0)
                throw new ArgumentOutOfRangeException("index",
                    index, "Argument cannot be negative.");

            if (index > this._count)
                throw new ArgumentOutOfRangeException("index",
                    index, "Argument cannot exceed Count.");

            if (this._count == this._keys.Length)
                EnsureCapacity(this._count + 1);

            ++this._version;
            if (index < this._count)
            {
                Array.Copy(this._keys, index,
                    this._keys, index + 1, this._count - index);

                Array.Copy(this._values, index,
                    this._values, index + 1, this._count - index);
            }

            this._keys[index] = entry.Key;
            this._values[index] = entry.Value;
            ++this._count;
        }

        #endregion
        #region IList.Insert(Int32, Object)

        /// <summary>
        /// Inserts an element into the <see cref="NameValueCollection"/> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which <paramref name="entry"/>
        /// should be inserted.</param>
        /// <param name="entry">The object to insert into the <see cref="NameValueCollection"/>.
        /// This argument must be compatible with <see cref="NameValueEntry"/>.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <exception cref="InvalidCastException"><paramref name="entry"/>
        /// is not compatible with <see cref="NameValueEntry"/>.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.Insert"/> for details.</remarks>

        void IList.Insert(int index, object entry)
        {
            Insert(index, (NameValueEntry)entry);
        }

        #endregion
        #region Remove(NameValueEntry)

        /// <summary>
        /// Removes the first occurrence of the specified <see cref="NameValueEntry"/>
        /// from the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="entry">The <see cref="NameValueEntry"/> object
        /// to remove from the <see cref="NameValueCollection"/>.</param>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.Remove"/> for details.</remarks>

        public virtual void Remove(NameValueEntry entry)
        {
            int index = IndexOf(entry);
            if (index >= 0) RemoveAt(index);
        }

        #endregion
        #region IList.Remove(Object)

        /// <summary>
        /// Removes the first occurrence of the specified <see cref="Object"/>
        /// from the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="entry">The object to remove from the <see cref="NameValueCollection"/>.
        /// This argument must be compatible with <see cref="NameValueEntry"/>.</param>
        /// <exception cref="InvalidCastException"><paramref name="entry"/>
        /// is not compatible with <see cref="NameValueEntry"/>.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.Remove"/> for details.</remarks>

        void IList.Remove(object entry)
        {
            Remove((NameValueEntry)entry);
        }

        #endregion
        #region RemoveAt

        /// <summary>
        /// Removes the element at the specified index of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="index">The zero-based index of the element to remove.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.RemoveAt"/> for details.</remarks>

        public virtual void RemoveAt(int index)
        {
            ValidateIndex(index);

            ++this._version;
            if (index < --this._count)
            {
                Array.Copy(this._keys, index + 1,
                    this._keys, index, this._count - index);

                Array.Copy(this._values, index + 1,
                    this._values, index, this._count - index);
            }

            this._keys[this._count] = null;
            this._values[this._count] = null;
        }

        #endregion
        #region SetByIndex

        /// <summary>
        /// Sets the <see cref="String"/> value at the
        /// specified index of the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="index">The zero-based index of the
        /// <see cref="String"/> value to set.</param>
        /// <param name="value">The <see cref="String"/> object to store
        /// at the specified <paramref name="index"/> of the <see cref="NameValueCollection"/>.
        /// This argument can be a null reference.
        /// </param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <para><paramref name="index"/> is less than zero.</para>
        /// <para>-or-</para>
        /// <para><paramref name="index"/> is equal to or greater than <see cref="Count"/>.</para>
        /// </exception>
        /// <remarks>Please refer to <see cref="SortedList.SetByIndex"/> for details.</remarks>

        public virtual void SetByIndex(int index, String value)
        {
            ValidateIndex(index);
            ++this._version;
            this._values[index] = value;
        }

        #endregion
        #region SetByKey

        /// <summary>
        /// Sets the <see cref="String"/> value associated with the
        /// first occurrence of the specified <see cref="String"/> key.
        /// </summary>
        /// <param name="key">The <see cref="String"/> key whose value to set.</param>
        /// <param name="value">The <see cref="String"/> object to associate with
        /// the first occurrence of the specified <paramref name="key"/>.
        /// This argument can be a null reference.
        /// If the specified <paramref name="key"/> is not found, <b>SetByKey</b> adds a new element
        /// with the specified <paramref name="key"/> and <paramref name="value"/> to the end of the
        /// <see cref="NameValueCollection"/>.</param>
        /// <returns>The <see cref="NameValueCollection"/> index of the element
        /// that was changed or added.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="key"/> is a null reference.</exception>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para><paramref name="key"/> does not exist in the collection,
        /// and the <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks><b>SetByKey</b> and <see cref="GetByKey"/> emulate the indexer of the
        /// <see cref="SortedList"/> class but require linear time to locate a key.</remarks>

        public virtual int SetByKey(String key, String value)
        {
            int index = IndexOfKey(key);

            if (index >= 0)
            {
                this._values[index] = value;
                return index;
            }

            return Add(key, value);
        }

        #endregion
        #region Synchronized

        /// <summary>
        /// Returns a synchronized (thread-safe) wrapper
        /// for the specified <see cref="NameValueCollection"/>.
        /// </summary>
        /// <param name="collection">The <see cref="NameValueCollection"/> to synchronize.</param>
        /// <returns>
        /// A synchronized (thread-safe) wrapper around <paramref name="collection"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="collection"/> is a null reference.</exception>
        /// <remarks>Please refer to <see cref="ArrayList.Synchronized"/> for details.</remarks>

        public static NameValueCollection Synchronized(NameValueCollection collection)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");

            return new SyncList(collection);
        }

        #endregion


        #region ToArray

        /// <summary>
        /// Copies the elements of the <see cref="NameValueCollection"/> to a new
        /// <see cref="Array"/> of <see cref="NameValueEntry"/> elements.
        /// </summary>
        /// <returns>A one-dimensional <see cref="Array"/> of <see cref="NameValueEntry"/>
        /// elements containing copies of the elements of the <see cref="NameValueCollection"/>.
        /// </returns>
        /// <remarks>Please refer to <see cref="ArrayList.ToArray"/> for details.</remarks>

        public virtual NameValueEntry[] ToArray()
        {
            NameValueEntry[] array = new NameValueEntry[this._count];
            CopyTo(array, 0);
            return array;
        }

        #endregion

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < this.Count; i++)
            {
                if (this[i].Key.IndexOf(';') >= 0 || this[i].Key.IndexOf('=') >= 0)
                {
                    sb.AppendFormat("\"{0}\"", this[i].Key.Replace("\"", "\"\""));
                }
                else
                {
                    sb.Append(this[i].Key);
                }
                
                sb.Append('=');

                if (this[i].Value.IndexOf(';') >= 0 || this[i].Value.IndexOf('=') >= 0)
                {
                    sb.AppendFormat("\"{0}\"", this[i].Value.Replace("\"", "\"\""));
                }
                else
                {
                    sb.Append(this[i].Value);
                }

                if (i < this.Count - 1)
                    sb.Append(";");
            }
            
            return sb.ToString();
        }

        #region TrimToSize

        /// <summary>
        /// Sets the capacity to the actual number of elements in the <see cref="NameValueCollection"/>.
        /// </summary>
        /// <exception cref="NotSupportedException">
        /// <para>The <see cref="NameValueCollection"/> is read-only.</para>
        /// <para>-or-</para>
        /// <para>The <b>NameValueCollection</b> has a fixed size.</para></exception>
        /// <remarks>Please refer to <see cref="ArrayList.TrimToSize"/> for details.</remarks>

        public virtual void TrimToSize()
        {
            Capacity = this._count;
        }

        #endregion
        #endregion
        #region Private Methods
        #region CheckEnumIndex

        private void CheckEnumIndex(int index)
        {
            if (index < 0 || index >= this._count)
                throw new InvalidOperationException(
                    "Enumerator is not on a collection element.");
        }

        #endregion
        #region CheckEnumVersion

        private void CheckEnumVersion(int version)
        {
            if (version != this._version)
                throw new InvalidOperationException(
                    "Enumerator invalidated by modification to collection.");
        }

        #endregion
        #region CheckTargetArray

        private void CheckTargetArray(Array array, int arrayIndex)
        {
            if (array == null)
                throw new ArgumentNullException("array");
            if (array.Rank > 1)
                throw new ArgumentException(
                    "Argument cannot be multidimensional.", "array");

            if (arrayIndex < 0)
                throw new ArgumentOutOfRangeException("arrayIndex",
                    arrayIndex, "Argument cannot be negative.");
            if (arrayIndex >= array.Length)
                throw new ArgumentException(
                    "Argument must be less than array length.", "arrayIndex");

            if (this._count > array.Length - arrayIndex)
                throw new ArgumentException(
                    "Argument section must be large enough for collection.", "array");
        }

        #endregion
        #region EnsureCapacity

        private void EnsureCapacity(int minimum)
        {
            int newCapacity = (this._keys.Length == 0 ?
                _defaultCapacity : this._keys.Length * 2);

            if (newCapacity < minimum) newCapacity = minimum;
            Capacity = newCapacity;
        }

        #endregion
        #region ValidateIndex

        private void ValidateIndex(int index)
        {
            if (index < 0)
                throw new ArgumentOutOfRangeException("index",
                    index, "Argument cannot be negative.");

            if (index >= this._count)
                throw new ArgumentOutOfRangeException("index",
                    index, "Argument must be less than Count.");
        }

        #endregion
        #endregion
        #region Class Enumerator

        [Serializable]
        private sealed class Enumerator :
            IStringStringEnumerator, IDictionaryEnumerator
        {
            #region Private Fields

            private readonly NameValueCollection _collection;
            private readonly int _version;
            private int _index;

            #endregion
            #region Internal Constructors

            internal Enumerator(NameValueCollection collection)
            {
                this._collection = collection;
                this._version = collection._version;
                this._index = -1;
            }

            #endregion
            #region Public Properties

            public NameValueEntry Current
            {
                get { return Entry; }
            }

            object IEnumerator.Current
            {
                get { return (DictionaryEntry)Entry; }
            }

            public NameValueEntry Entry
            {
                get
                {
                    this._collection.CheckEnumIndex(this._index);
                    this._collection.CheckEnumVersion(this._version);

                    return new NameValueEntry(
                        this._collection._keys[this._index],
                        this._collection._values[this._index]);
                }
            }

            DictionaryEntry IDictionaryEnumerator.Entry
            {
                get { return Entry; }
            }

            public String Key
            {
                get
                {
                    this._collection.CheckEnumIndex(this._index);
                    this._collection.CheckEnumVersion(this._version);
                    return this._collection._keys[this._index];
                }
            }

            object IDictionaryEnumerator.Key
            {
                get { return Key; }
            }

            public String Value
            {
                get
                {
                    this._collection.CheckEnumIndex(this._index);
                    this._collection.CheckEnumVersion(this._version);
                    return this._collection._values[this._index];
                }
            }

            object IDictionaryEnumerator.Value
            {
                get { return Value; }
            }

            #endregion
            #region Public Methods

            public bool MoveNext()
            {
                this._collection.CheckEnumVersion(this._version);
                return (++this._index < this._collection.Count);
            }

            public void Reset()
            {
                this._collection.CheckEnumVersion(this._version);
                this._index = -1;
            }

            #endregion
        }

        #endregion
        #region Class KeyList

        [Serializable]
        private sealed class KeyList : IStringList, IList
        {
            #region Private Fields

            private NameValueCollection _collection;

            #endregion
            #region Internal Constructors

            internal KeyList(NameValueCollection collection)
            {
                this._collection = collection;
            }

            #endregion
            #region Public Properties

            public int Count
            {
                get { return this._collection.Count; }
            }

            public bool IsReadOnly
            {
                get { return true; }
            }

            public bool IsFixedSize
            {
                get { return true; }
            }

            public bool IsSynchronized
            {
                get { return this._collection.IsSynchronized; }
            }

            public String this[int index]
            {
                get { return this._collection.GetKey(index); }
                set
                {
                    throw new NotSupportedException(
                      "Read-only collections cannot be modified.");
                }
            }

            object IList.this[int index]
            {
                get { return this[index]; }
                set
                {
                    throw new NotSupportedException(
                      "Read-only collections cannot be modified.");
                }
            }

            public object SyncRoot
            {
                get { return this._collection.SyncRoot; }
            }

            #endregion
            #region Public Methods

            public int Add(String key)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            int IList.Add(object key)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public void Clear()
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public bool Contains(String key)
            {
                return this._collection.ContainsKey(key);
            }

            bool IList.Contains(object key)
            {
                return Contains((String)key);
            }

            public void CopyTo(String[] array, int arrayIndex)
            {
                this._collection.CheckTargetArray(array, arrayIndex);
                Array.Copy(this._collection._keys, 0,
                    array, arrayIndex, this._collection.Count);
            }

            void ICollection.CopyTo(Array array, int arrayIndex)
            {
                this._collection.CheckTargetArray(array, arrayIndex);
                CopyTo((String[])array, arrayIndex);
            }

            public IStringEnumerator GetEnumerator()
            {
                return new KeyEnumerator(this._collection);
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return (IEnumerator)GetEnumerator();
            }

            public int IndexOf(String key)
            {
                return this._collection.IndexOfKey(key);
            }

            int IList.IndexOf(object key)
            {
                return IndexOf((String)key);
            }

            public void Insert(int index, String key)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            void IList.Insert(int index, object key)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public void Remove(String key)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            void IList.Remove(object key)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public void RemoveAt(int index)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            #endregion
        }

        #endregion
        #region Class KeyEnumerator

        [Serializable]
        private sealed class KeyEnumerator :
            IStringEnumerator, IEnumerator
        {
            #region Private Fields

            private readonly NameValueCollection _collection;
            private readonly int _version;
            private int _index;

            #endregion
            #region Internal Constructors

            internal KeyEnumerator(NameValueCollection collection)
            {
                this._collection = collection;
                this._version = collection._version;
                this._index = -1;
            }

            #endregion
            #region Public Properties

            public String Current
            {
                get
                {
                    this._collection.CheckEnumIndex(this._index);
                    this._collection.CheckEnumVersion(this._version);
                    return this._collection._keys[this._index];
                }
            }

            object IEnumerator.Current
            {
                get { return Current; }
            }

            #endregion
            #region Public Methods

            public bool MoveNext()
            {
                this._collection.CheckEnumVersion(this._version);
                return (++this._index < this._collection.Count);
            }

            public void Reset()
            {
                this._collection.CheckEnumVersion(this._version);
                this._index = -1;
            }

            #endregion
        }

        #endregion
        #region Class ValueList

        [Serializable]
        private sealed class ValueList : IStringList, IList
        {
            #region Private Fields

            private NameValueCollection _collection;

            #endregion
            #region Internal Constructors

            internal ValueList(NameValueCollection collection)
            {
                this._collection = collection;
            }

            #endregion
            #region Public Properties

            public int Count
            {
                get { return this._collection.Count; }
            }

            public bool IsReadOnly
            {
                get { return true; }
            }

            public bool IsFixedSize
            {
                get { return true; }
            }

            public bool IsSynchronized
            {
                get { return this._collection.IsSynchronized; }
            }

            public String this[int index]
            {
                get { return this._collection.GetByIndex(index); }
                set
                {
                    throw new NotSupportedException(
                  "Read-only collections cannot be modified.");
                }
            }

            object IList.this[int index]
            {
                get { return this[index]; }
                set
                {
                    throw new NotSupportedException(
                  "Read-only collections cannot be modified.");
                }
            }

            public object SyncRoot
            {
                get { return this._collection.SyncRoot; }
            }

            #endregion
            #region Public Methods

            public int Add(String value)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            int IList.Add(object value)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public void Clear()
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public bool Contains(String value)
            {
                return this._collection.ContainsValue(value);
            }

            bool IList.Contains(object value)
            {
                return Contains((String)value);
            }

            public void CopyTo(String[] array, int arrayIndex)
            {
                this._collection.CheckTargetArray(array, arrayIndex);
                Array.Copy(this._collection._values, 0,
                    array, arrayIndex, this._collection.Count);
            }

            void ICollection.CopyTo(Array array, int arrayIndex)
            {
                this._collection.CheckTargetArray(array, arrayIndex);
                CopyTo((String[])array, arrayIndex);
            }

            public IStringEnumerator GetEnumerator()
            {
                return new ValueEnumerator(this._collection);
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return (IEnumerator)GetEnumerator();
            }

            public int IndexOf(String value)
            {
                return this._collection.IndexOfValue(value);
            }

            int IList.IndexOf(object value)
            {
                return IndexOf((String)value);
            }

            public void Insert(int index, String value)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            void IList.Insert(int index, object value)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public void Remove(String value)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            void IList.Remove(object value)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            public void RemoveAt(int index)
            {
                throw new NotSupportedException(
                    "Read-only collections cannot be modified.");
            }

            #endregion
        }

        #endregion
        #region Class ValueEnumerator

        [Serializable]
        private sealed class ValueEnumerator :
            IStringEnumerator, IEnumerator
        {
            #region Private Fields

            private readonly NameValueCollection _collection;
            private readonly int _version;
            private int _index;

            #endregion
            #region Internal Constructors

            internal ValueEnumerator(NameValueCollection collection)
            {
                this._collection = collection;
                this._version = collection._version;
                this._index = -1;
            }

            #endregion
            #region Public Properties

            public String Current
            {
                get
                {
                    this._collection.CheckEnumIndex(this._index);
                    this._collection.CheckEnumVersion(this._version);
                    return this._collection._values[this._index];
                }
            }

            object IEnumerator.Current
            {
                get { return Current; }
            }

            #endregion
            #region Public Methods

            public bool MoveNext()
            {
                this._collection.CheckEnumVersion(this._version);
                return (++this._index < this._collection.Count);
            }

            public void Reset()
            {
                this._collection.CheckEnumVersion(this._version);
                this._index = -1;
            }

            #endregion
        }

        #endregion
        #region Class SyncList

        [Serializable]
        private sealed class SyncList : NameValueCollection
        {
            #region Private Fields

            private NameValueCollection _collection;
            private object _root;

            #endregion
            #region Internal Constructors

            internal SyncList(NameValueCollection collection)
                :
                base(Tag.Default)
            {

                this._collection = collection;
                this._root = collection.SyncRoot;
            }

            #endregion
            #region Protected Properties

            protected override String[] InnerKeys
            {
                get { lock (this._root) return this._collection.InnerKeys; }
            }

            protected override String[] InnerValues
            {
                get { lock (this._root) return this._collection.InnerValues; }
            }

            #endregion
            #region Public Properties

            public override int Capacity
            {
                get { lock (this._root) return this._collection.Capacity; }
            }

            public override int Count
            {
                get { lock (this._root) return this._collection.Count; }
            }

            public override bool IsFixedSize
            {
                get { return this._collection.IsFixedSize; }
            }

            public override bool IsReadOnly
            {
                get { return this._collection.IsReadOnly; }
            }

            public override bool IsSynchronized
            {
                get { return true; }
            }

            public override NameValueEntry this[int index]
            {
                get { lock (this._root) return this._collection[index]; }
                set { lock (this._root) this._collection[index] = value; }
            }

            public override IStringCollection Keys
            {
                get { lock (this._root) return this._collection.Keys; }
            }

            public override object SyncRoot
            {
                get { return this._root; }
            }

            public override IStringCollection Values
            {
                get { lock (this._root) return this._collection.Values; }
            }

            #endregion
            #region Public Methods

            public override int Add(NameValueEntry entry)
            {
                lock (this._root) return this._collection.Add(entry);
            }

            public override void AddRange(NameValueCollection collection)
            {
                lock (this._root) this._collection.AddRange(collection);
            }

            public override void AddRange(NameValueEntry[] array)
            {
                lock (this._root) this._collection.AddRange(array);
            }

            public override void Clear()
            {
                lock (this._root) this._collection.Clear();
            }

            public override object Clone()
            {
                lock (this._root)
                    return new SyncList((NameValueCollection)this._collection.Clone());
            }

            public override void CopyTo(NameValueEntry[] array, int index)
            {
                lock (this._root) this._collection.CopyTo(array, index);
            }

            public override bool Equals(NameValueCollection collection)
            {
                lock (this._root) return this._collection.Equals(collection);
            }

            public override String GetByIndex(int index)
            {
                lock (this._root) return this._collection.GetByIndex(index);
            }

            public override String GetByKey(String key)
            {
                lock (this._root) return this._collection.GetByKey(key);
            }

            public override IStringStringEnumerator GetEnumerator()
            {
                lock (this._root) return this._collection.GetEnumerator();
            }

            public override String GetKey(int index)
            {
                lock (this._root) return this._collection.GetKey(index);
            }

            public override IStringList GetKeyList()
            {
                lock (this._root) return this._collection.GetKeyList();
            }

            public override IStringList GetValueList()
            {
                lock (this._root) return this._collection.GetValueList();
            }

            public override int IndexOf(NameValueEntry entry)
            {
                lock (this._root) return this._collection.IndexOf(entry);
            }

            public override int IndexOfKey(String key)
            {
                lock (this._root) return this._collection.IndexOfKey(key);
            }

            public override int IndexOfValue(String value)
            {
                lock (this._root) return this._collection.IndexOfValue(value);
            }

            public override void Insert(int index, NameValueEntry entry)
            {
                lock (this._root) this._collection.Insert(index, entry);
            }

            public override void Remove(NameValueEntry entry)
            {
                lock (this._root) this._collection.Remove(entry);
            }

            public override void RemoveAt(int index)
            {
                lock (this._root) this._collection.RemoveAt(index);
            }

            public override void SetByIndex(int index, String value)
            {
                lock (this._root) this._collection.SetByIndex(index, value);
            }

            public override int SetByKey(String key, String value)
            {
                lock (this._root) return this._collection.SetByKey(key, value);
            }

            public override NameValueEntry[] ToArray()
            {
                lock (this._root) return this._collection.ToArray();
            }

            public override void TrimToSize()
            {
                lock (this._root) this._collection.TrimToSize();
            }

            #endregion
        }

        #endregion
    }

    #endregion
}
