You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2016/10/02 15:02:34 UTC

[08/10] lucenenet git commit: Fixed several CharArraySet/CharArrayMap bugs that were causing tests to fail, and re-enabled those tests. Refactored both classes to be more .NET-like.

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/87d05125/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs
index 9b5e0e6..33e69eb 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs
@@ -1,7 +1,10 @@
 \ufeffusing Lucene.Net.Support;
 using Lucene.Net.Util;
+using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
 using System.Linq;
 using System.Text;
 
@@ -25,17 +28,17 @@ namespace Lucene.Net.Analysis.Util
 	 */
 
     /// <summary>
-    /// A simple class that stores Strings as char[]'s in a
+    /// A simple class that stores <see cref="string"/>s as <see cref="char[]"/>'s in a
     /// hash table.  Note that this is not a general purpose
     /// class.  For example, it cannot remove items from the
     /// set, nor does it resize its hash table to be smaller,
-    /// etc.  It is designed to be quick to test if a char[]
+    /// etc.  It is designed to be quick to test if a <see cref="char[]"/>
     /// is in the set without the necessity of converting it
-    /// to a String first.
+    /// to a <see cref="string"/> first.
     /// 
     /// <a name="version"></a>
-    /// <p>You must specify the required <seealso cref="LuceneVersion"/>
-    /// compatibility when creating <seealso cref="CharArraySet"/>:
+    /// <para>You must specify the required <see cref="LuceneVersion"/>
+    /// compatibility when creating <see cref="CharArraySet"/>:
     /// <ul>
     ///   <li> As of 3.1, supplementary characters are
     ///       properly lowercased.</li>
@@ -43,27 +46,28 @@ namespace Lucene.Net.Analysis.Util
     /// Before 3.1 supplementary characters could not be
     /// lowercased correctly due to the lack of Unicode 4
     /// support in JDK 1.4. To use instances of
-    /// <seealso cref="CharArraySet"/> with the behavior before Lucene
-    /// 3.1 pass a <seealso cref="LuceneVersion"/> to the constructors.
-    /// <p>
-    /// <em>Please note:</em> This class implements <seealso cref="java.util.Set Set"/> but
+    /// <see cref="CharArraySet"/> with the behavior before Lucene
+    /// 3.1 pass a <see cref="LuceneVersion"/> to the constructors.
+    /// </para>
+    /// <para>
+    /// <em>Please note:</em> This class implements <see cref="ISet{T}"/> but
     /// does not behave like it should in all cases. The generic type is
-    /// {@code Set<Object>}, because you can add any object to it,
-    /// that has a string representation. The add methods will use
-    /// <seealso cref="object#toString"/> and store the result using a {@code char[]}
-    /// buffer. The same behavior have the {@code contains()} methods.
-    /// The <seealso cref="#iterator()"/> returns an {@code Iterator<char[]>}.
-    /// </p>
+    /// <see cref="string"/>, because you can add any object to it,
+    /// that has a string representation (which is converted to a string). The add methods will use
+    /// <see cref="object.ToString()"/> and store the result using a <see cref="char[]"/>
+    /// buffer. The same behavior have the <see cref="Contains(string)"/> methods.
+    /// The <see cref="GetEnumerator()"/> returns an <see cref="IEnumerator{Char[]}"/>
+    /// </para>
     /// </summary>
-    public class CharArraySet : ISet<object>
+    public class CharArraySet : ISet<string>
     {
-        public static readonly CharArraySet EMPTY_SET = new CharArraySet(CharArrayMap<object>.EmptyMap());
-        private static readonly object PLACEHOLDER = new object();
+        public static readonly CharArraySet EMPTY_SET = new CharArraySet(CharArrayMap<string>.EmptyMap());
+        // LUCENENET: PLACEHOLDER moved to CharArrayMap
 
-        internal readonly CharArrayMap<object> map;
+        internal readonly ICharArrayMap map;
 
         /// <summary>
-        /// Create set with enough capacity to hold startSize terms
+        /// Create set with enough capacity to hold <paramref name="startSize"/> terms
         /// </summary>
         /// <param name="matchVersion">
         ///          compatibility match version see <a href="#version">Version
@@ -71,15 +75,15 @@ namespace Lucene.Net.Analysis.Util
         /// <param name="startSize">
         ///          the initial capacity </param>
         /// <param name="ignoreCase">
-        ///          <code>false</code> if and only if the set should be case sensitive
-        ///          otherwise <code>true</code>. </param>
+        ///          <c>false</c> if and only if the set should be case sensitive
+        ///          otherwise <c>true</c>. </param>
         public CharArraySet(LuceneVersion matchVersion, int startSize, bool ignoreCase)
             : this(new CharArrayMap<object>(matchVersion, startSize, ignoreCase))
         {
         }
 
         /// <summary>
-        /// Creates a set from a Collection of objects. 
+        /// Creates a set from a collection of objects. 
         /// </summary>
         /// <param name="matchVersion">
         ///          compatibility match version see <a href="#version">Version
@@ -87,24 +91,24 @@ namespace Lucene.Net.Analysis.Util
         /// <param name="c">
         ///          a collection whose elements to be placed into the set </param>
         /// <param name="ignoreCase">
-        ///          <code>false</code> if and only if the set should be case sensitive
-        ///          otherwise <code>true</code>. </param>
-        public CharArraySet(LuceneVersion matchVersion, IEnumerable<object> c, bool ignoreCase)
+        ///          <c>false</c> if and only if the set should be case sensitive
+        ///          otherwise <c>true</c>. </param>
+        public CharArraySet(LuceneVersion matchVersion, IEnumerable<string> c, bool ignoreCase)
             : this(matchVersion, c.Count(), ignoreCase)
         {
-            this.AddAll(c);
+            this.UnionWith(c);
         }
 
         /// <summary>
-        /// Create set from the specified map (internal only), used also by <seealso cref="CharArrayMap#KeySet()"/>
+        /// Create set from the specified map (internal only), used also by <see cref="CharArrayMap{TValue}.Keys"/>
         /// </summary>
-        internal CharArraySet(CharArrayMap<object> map)
+        internal CharArraySet(ICharArrayMap map)
         {
             this.map = map;
         }
 
         /// <summary>
-        /// Clears all entries in this set. This method is supported for reusing, but not <seealso cref="Set#Remove"/>.
+        /// Clears all entries in this set. This method is supported for reusing, but not <see cref="ICollection{Object}.Remove(string)"/>.
         /// </summary>
         public virtual void Clear()
         {
@@ -112,234 +116,1304 @@ namespace Lucene.Net.Analysis.Util
         }
 
         /// <summary>
-        /// true if the <code>len</code> chars of <code>text</code> starting at <code>off</code>
+        /// <c>true</c> if the <paramref name="length"/> chars of <paramref name="text"/> starting at <paramref name="offset"/>
         /// are in the set 
         /// </summary>
-        public virtual bool Contains(char[] text, int off, int len)
+        public virtual bool Contains(char[] text, int offset, int length)
         {
-            return map.ContainsKey(text, off, len);
+            return map.ContainsKey(text, offset, length);
         }
 
         /// <summary>
-        /// true if the <code>CharSequence</code> is in the set </summary>
-        public virtual bool Contains(string cs)
+        /// <c>true</c> if the <see cref="char[]"/>s 
+        /// are in the set 
+        /// </summary>
+        public virtual bool Contains(char[] text)
         {
-            return map.ContainsKey(cs);
+            return map.ContainsKey(text, 0, text.Length);
         }
 
-        public virtual bool Contains(object o)
+        /// <summary>
+        /// <c>true</c> if the <see cref="ICharSequence"/> is in the set
+        /// </summary>
+        public virtual bool Contains(ICharSequence cs)
         {
-            return map.ContainsKey(o);
+            return map.ContainsKey(cs);
         }
 
-        public void CopyTo(object[] array, int arrayIndex)
+        /// <summary>
+        /// <c>true</c> if the <see cref="string"/> is in the set
+        /// </summary>
+        public virtual bool Contains(string cs)
         {
-            throw new System.NotImplementedException();
+            return map.ContainsKey(cs);
         }
 
-        public virtual bool Remove(object item)
+        /// <summary>
+        /// <c>true</c> if the <see cref="object.ToString()"/> representation of <paramref name="o"/> is in the set
+        /// </summary>
+        public virtual bool Contains(object o)
         {
-            return map.Remove(item);
+            return map.ContainsKey(o);
         }
 
+        /// <summary>
+        /// Add the <see cref="object.ToString()"/> representation of <paramref name="o"/> into the set.
+        /// The <see cref="object.ToString()"/> method is called after setting the thread to <see cref="CultureInfo.InvariantCulture"/>.
+        /// If the type of <paramref name="o"/> is a value type, it will be converted using the 
+        /// <see cref="CultureInfo.InvariantCulture"/>.
+        /// </summary>
+        /// <param name="o">A string-able object</param>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
         public virtual bool Add(object o)
         {
-            return map.Put(o, PLACEHOLDER) == null;
+            return map.Put(o);
+        }
+
+        /// <summary>
+        /// Add this <see cref="ICharSequence"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public virtual bool Add(ICharSequence text)
+        {
+            return map.Put(text);
         }
 
         /// <summary>
-        /// Add this String into the set </summary>
+        /// Add this <see cref="string"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
         public virtual bool Add(string text)
         {
-            return map.Put(text, PLACEHOLDER) == null;
+            return map.Put(text);
         }
 
         /// <summary>
-        /// Add this char[] directly to the set.
-        /// If ignoreCase is true for this Set, the text array will be directly modified.
+        /// Add this <see cref="char[]"/> directly to the set.
+        /// If <see cref="ignoreCase"/> is true for this <see cref="CharArraySet"/>, the text array will be directly modified.
         /// The user should never modify this text array after calling this method.
         /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
         public virtual bool Add(char[] text)
         {
-            return map.Put(text, PLACEHOLDER) == null;
+            return map.Put(text);
         }
 
-        void ICollection<object>.Add(object item)
+        /// <summary>
+        /// LUCENENET specific for supporting <see cref="ICollection{T}"/>.
+        /// </summary>
+        void ICollection<string>.Add(string item)
         {
             Add(item);
         }
 
+        /// <summary>
+        /// Gets the number of elements contained in the <see cref="CharArraySet"/>.
+        /// </summary>
         public virtual int Count
         {
             get { return map.Count; }
         }
 
+        /// <summary>
+        /// <c>true</c> if the <see cref="CharArraySet"/> is read-only; otherwise <c>false</c>.
+        /// </summary>
         public virtual bool IsReadOnly { get; private set; }
 
         /// <summary>
-        /// Returns an unmodifiable <seealso cref="CharArraySet"/>. This allows to provide
+        /// Returns an unmodifiable <see cref="CharArraySet"/>. This allows to provide
         /// unmodifiable views of internal sets for "read-only" use.
         /// </summary>
         /// <param name="set">
         ///          a set for which the unmodifiable set is returned. </param>
-        /// <returns> an new unmodifiable <seealso cref="CharArraySet"/>. </returns>
-        /// <exception cref="NullPointerException">
-        ///           if the given set is <code>null</code>. </exception>
+        /// <returns> an new unmodifiable <see cref="CharArraySet"/>. </returns>
+        /// <exception cref="ArgumentNullException">
+        ///           if the given set is <c>null</c>. </exception>
         public static CharArraySet UnmodifiableSet(CharArraySet set)
         {
             if (set == null)
             {
-                throw new System.NullReferenceException("Given set is null");
+                throw new System.ArgumentNullException("Given set is null");
             }
             if (set == EMPTY_SET)
             {
                 return EMPTY_SET;
             }
-            if (set.map is CharArrayMap<object>.UnmodifiableCharArrayMap<object>)
+            if (set.map is CharArrayMap.UnmodifiableCharArrayMap<object>)
             {
                 return set;
             }
-            return new CharArraySet(CharArrayMap<object>.UnmodifiableMap(set.map));
+            return new CharArraySet(CharArrayMap.UnmodifiableMap<object>(set.map));
         }
 
         /// <summary>
-        /// Returns a copy of the given set as a <seealso cref="CharArraySet"/>. If the given set
-        /// is a <seealso cref="CharArraySet"/> the ignoreCase property will be preserved.
+        /// Returns a copy of the given set as a <see cref="CharArraySet"/>. If the given set
+        /// is a <see cref="CharArraySet"/> the ignoreCase property will be preserved.
         /// <para>
-        /// <b>Note:</b> If you intend to create a copy of another <seealso cref="CharArraySet"/> where
-        /// the <seealso cref="LuceneVersion"/> of the source set differs from its copy
-        /// <seealso cref="#CharArraySet(Version, Collection, boolean)"/> should be used instead.
-        /// The <seealso cref="#copy(Version, Set)"/> will preserve the <seealso cref="LuceneVersion"/> of the
-        /// source set it is an instance of <seealso cref="CharArraySet"/>.
+        /// <b>Note:</b> If you intend to create a copy of another <see cref="CharArraySet"/> where
+        /// the <see cref="LuceneVersion"/> of the source set differs from its copy
+        /// <see cref="CharArraySet(LuceneVersion, IEnumerable{string}, bool)"/> should be used instead.
+        /// The <see cref="Copy{T}(LuceneVersion, IEnumerable{T})"/> will preserve the <see cref="LuceneVersion"/> of the
+        /// source set it is an instance of <see cref="CharArraySet"/>.
         /// </para>
         /// </summary>
         /// <param name="matchVersion">
         ///          compatibility match version see <a href="#version">Version
         ///          note</a> above for details. This argument will be ignored if the
-        ///          given set is a <seealso cref="CharArraySet"/>. </param>
+        ///          given set is a <see cref="CharArraySet"/>. </param>
         /// <param name="set">
         ///          a set to copy </param>
-        /// <returns> a copy of the given set as a <seealso cref="CharArraySet"/>. If the given set
-        ///         is a <seealso cref="CharArraySet"/> the ignoreCase property as well as the
-        ///         matchVersion will be of the given set will be preserved. </returns>
-        public static CharArraySet Copy<T1>(LuceneVersion matchVersion, ISet<T1> set)
+        /// <returns> a copy of the given set as a <see cref="CharArraySet"/>. If the given set
+        ///         is a <see cref="CharArraySet"/> the <see cref="CharArrayMap{TValue}.ignoreCase"/> field as well as the
+        ///         <see cref="CharArrayMap{TValue}.MatchVersion"/> will be preserved. </returns>
+        public static CharArraySet Copy<T>(LuceneVersion matchVersion, IEnumerable<T> set)
         {
             if (set == EMPTY_SET)
             {
                 return EMPTY_SET;
             }
 
-            var source = set as CharArraySet;
-            if (source != null)
+            // LUCENENET NOTE: Testing for *is* is at least 10x faster
+            // than casting using *as* and then checking for null.
+            // http://stackoverflow.com/q/1583050/181087
+            if (set is CharArraySet)
             {
-                return new CharArraySet(CharArrayMap<object>.Copy(source.map.matchVersion, source.map));
+                var source = set as CharArraySet;
+                return new CharArraySet(CharArrayMap.Copy<object>(source.map.MatchVersion, source.map));
             }
 
-            return new CharArraySet(matchVersion, set.Cast<object>(), false);
+            // Convert the elements in the collection to string in the invariant context.
+            string[] stringSet;
+            using (var context = new CultureContext(CultureInfo.InvariantCulture))
+            {
+                stringSet = set.Select(x => x.ToString()).ToArray();
+            }
+
+            return new CharArraySet(matchVersion, stringSet, false);
         }
 
         /// <summary>
-        /// Returns an <seealso cref="IEnumerator"/> for {@code char[]} instances in this set.
+        /// Returns an <see cref="IEnumerator"/> for <see cref="char[]"/> instances in this set.
         /// </summary>
         public virtual IEnumerator GetEnumerator()
         {
-            // use the AbstractSet#keySet()'s iterator (to not produce endless recursion)
-            return map.OriginalKeySet().GetEnumerator();
+            // use the OriginalKeySet's enumerator (to not produce endless recursion)
+            return map.OriginalKeySet.GetEnumerator();
         }
 
-        IEnumerator<object> IEnumerable<object>.GetEnumerator()
+        IEnumerator<string> IEnumerable<string>.GetEnumerator()
         {
-            // use the AbstractSet#keySet()'s iterator (to not produce endless recursion)
-            return map.OriginalKeySet().GetEnumerator();
+            // use the OriginalKeySet's enumerator (to not produce endless recursion)
+            return (IEnumerator<string>)map.OriginalKeySet.GetEnumerator();
         }
 
+        /// <summary>
+        /// Returns a string that represents the current object. (Inherited from <see cref="object"/>.)
+        /// </summary>
         public override string ToString()
         {
             var sb = new StringBuilder("[");
-            foreach (object item in this)
+            foreach (var item in this)
             {
                 if (sb.Length > 1)
                 {
                     sb.Append(", ");
                 }
+                sb.Append(item);
+            }
+            return sb.Append(']').ToString();
+        }
+
+        #region LUCENENET specific members
+
+        /// <summary>
+        /// Copies the entire <see cref="CharArraySet"/> to a one-dimensional <see cref="string[]"/> array, 
+        /// starting at the specified index of the target array.
+        /// </summary>
+        /// <param name="array">The one-dimensional <see cref="string[]"/> Array that is the destination of the 
+        /// elements copied from <see cref="CharArraySet"/>. The Array must have zero-based indexing.</param>
+        /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
+        public void CopyTo(string[] array, int arrayIndex)
+        {
+            var iter = map.OriginalKeySet.GetEnumerator();
+            for (int i = arrayIndex; iter.MoveNext(); i++)
+            {
+                array[i] = iter.Current;
+            }
+        }
+
+        [Obsolete("Not applicable in this class.")]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual bool Remove(string item)
+        {
+            // LUCENENET NOTE: According to the documentation header, Remove should not be supported
+            throw new NotSupportedException();
+        }
+
+        // LUCENENET - Added to ensure equality checking works in tests
+        /// <summary>
+        /// Determines whether the current set and the specified collection contain the same elements.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current set.</param>
+        /// <returns><c>true</c> if the current set is equal to other; otherwise, <c>false</c>.</returns>
+        public virtual bool SetEquals(IEnumerable<string> other)
+        {
+            var otherSet = other as CharArraySet;
+            if (otherSet == null)
+                return false;
+
+            // Invoke the implementation on CharArrayMap that
+            // tests the dictionaries to ensure they contain
+            // the same keys and values.
+            return this.map.Equals(otherSet.map);
+        }
+
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public virtual bool UnionWith(IEnumerable<char[]> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (Add(item))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
+        }
+
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public virtual bool UnionWith(IEnumerable<ICharSequence> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (Add(item))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
+        }
+
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        public virtual void UnionWith(IEnumerable<string> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            foreach (var item in other)
+            {
+                Add(item);
+            }
+        }
+
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public virtual bool UnionWith<T>(IEnumerable<T> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
                 if (item is char[])
                 {
-                    sb.Append((char[])item);
+                    if (Add(item as char[]))
+                    {
+                        modified = true;
+                    }
+                    continue;
                 }
-                else
+
+                // Convert the item to a string in the invariant culture
+                string stringItem;
+                using (var context = new CultureContext(CultureInfo.InvariantCulture))
+                {
+                    stringItem = item.ToString();
+                }
+
+                if (Add(stringItem))
                 {
-                    sb.Append(item);
+                    modified = true;
                 }
             }
-            return sb.Append(']').ToString();
+            return modified;
         }
 
-        // LUCENENET - Added to ensure equality checking works in tests
-        public bool SetEquals(IEnumerable<object> other)
+        // LUCENENET - no modifications should be made outside of original
+        // Java implmentation's methods.
+        [Obsolete("Not applicable in this class.")]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
+        public void IntersectWith(IEnumerable<string> other)
         {
-            var otherSet = other as CharArraySet;
-            if (otherSet == null)
+            throw new NotSupportedException();
+        }
+
+        // LUCENENET - no modifications should be made outside of original
+        // Java implmentation's methods.
+        [Obsolete("Not applicable in this class.")]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
+        public void ExceptWith(IEnumerable<string> other)
+        {
+            throw new NotSupportedException();
+        }
+
+        // LUCENENET - no modifications should be made outside of original
+        // Java implmentation's methods.
+        [Obsolete("Not applicable in this class.")]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
+        public void SymmetricExceptWith(IEnumerable<string> other)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a subset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the <see cref="CharArraySet"/> object is a subset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsSubsetOf(IEnumerable<string> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (this.Count == 0)
+            {
+                return true;
+            }
+            CharArraySet set = other as CharArraySet;
+            if (set != null)
+            {
+                if (this.Count > set.Count)
+                {
+                    return false;
+                }
+                return this.IsSubsetOfCharArraySet(set);
+            }
+            // we just need to return true if the other set
+            // contains all of the elements of the this set,
+            // but we need to use the comparison rules of the current set.
+            int foundCount, unfoundCount;
+            this.GetFoundAndUnfoundCounts(other, out foundCount, out unfoundCount);
+            return foundCount == this.Count;
+        }
+
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a subset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the <see cref="CharArraySet"/> object is a subset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsSubsetOf<T>(IEnumerable<T> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (this.Count == 0)
+            {
+                return true;
+            }
+            // we just need to return true if the other set
+            // contains all of the elements of the this set,
+            // but we need to use the comparison rules of the current set.
+            int foundCount, unfoundCount;
+            this.GetFoundAndUnfoundCounts(other, out foundCount, out unfoundCount);
+            return foundCount == this.Count;
+        }
+
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a superset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the HashSet<T> object is a superset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsSupersetOf(IEnumerable<string> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            ICollection<string> is2 = other as ICollection<string>;
+            if (is2 != null)
+            {
+                if (is2.Count == 0)
+                {
+                    return true;
+                }
+                CharArraySet set = other as CharArraySet;
+                if ((set != null) && (set.Count > this.Count))
+                {
+                    return false;
+                }
+            }
+            return this.ContainsAll(other);
+        }
+
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a superset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the HashSet<T> object is a superset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsSupersetOf<T>(IEnumerable<T> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            ICollection<T> is2 = other as ICollection<T>;
+            if (is2 != null && is2.Count == 0)
+            {
+                return true;
+            }
+            return this.ContainsAll(other);
+        }
+
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a proper subset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the <see cref="CharArraySet"/> object is a proper subset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsProperSubsetOf(IEnumerable<string> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            ICollection<string> is2 = other as ICollection<string>;
+            if (is2 != null)
+            {
+                if (this.Count == 0)
+                {
+                    return (is2.Count > 0);
+                }
+                CharArraySet set = other as CharArraySet;
+                if (set != null)
+                {
+                    if (this.Count >= set.Count)
+                    {
+                        return false;
+                    }
+                    return this.IsSubsetOfCharArraySet(set);
+                }
+            }
+            // we just need to return true if the other set
+            // contains all of the elements of the this set plus at least one more,
+            // but we need to use the comparison rules of the current set.
+            int foundCount, unfoundCount;
+            this.GetFoundAndUnfoundCounts(other, out foundCount, out unfoundCount);
+            return foundCount == this.Count && unfoundCount > 0;
+        }
+
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a proper subset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the <see cref="CharArraySet"/> object is a proper subset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsProperSubsetOf<T>(IEnumerable<T> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            ICollection<T> is2 = other as ICollection<T>;
+            if (is2 != null && this.Count == 0)
+            {
+                return (is2.Count > 0);
+            }
+            // we just need to return true if the other set
+            // contains all of the elements of the this set plus at least one more,
+            // but we need to use the comparison rules of the current set.
+            int foundCount, unfoundCount;
+            this.GetFoundAndUnfoundCounts(other, out foundCount, out unfoundCount);
+            return foundCount == this.Count && unfoundCount > 0;
+        }
+
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a proper superset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the HashSet<T> object is a proper superset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsProperSupersetOf(IEnumerable<string> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (this.Count == 0)
+            {
                 return false;
+            }
+            ICollection<string> is2 = other as ICollection<string>;
+            if (is2 != null)
+            {
+                if (is2.Count == 0)
+                {
+                    return true;
+                }
+                CharArraySet set = other as CharArraySet;
+                if (set != null)
+                {
+                    if (set.Count >= this.Count)
+                    {
+                        return false;
+                    }
+                    return this.ContainsAll(set);
+                }
+            }
+            int foundCount, unfoundCount;
+            this.GetFoundAndUnfoundCounts(other, out foundCount, out unfoundCount);
+            return foundCount < this.Count && unfoundCount == 0;
+        }
 
-            if (this.Count != otherSet.Count)
+        /// <summary>
+        /// Determines whether a <see cref="CharArraySet"/> object is a proper superset of the specified collection.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the HashSet<T> object is a proper superset of <paramref name="other"/>; otherwise, <c>false</c>.</returns>
+        public virtual bool IsProperSupersetOf<T>(IEnumerable<T> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (this.Count == 0)
+            {
                 return false;
+            }
+            ICollection<T> is2 = other as ICollection<T>;
+            if (is2 != null && is2.Count == 0)
+            {
+                return true;
+            }
+            int foundCount, unfoundCount;
+            this.GetFoundAndUnfoundCounts(other, out foundCount, out unfoundCount);
+            return foundCount < this.Count && unfoundCount == 0;
+        }
+
+        /// <summary>
+        /// Determines whether the current <see cref="CharArraySet"/> object and a specified collection share common elements.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the HashSet<T> object and <paramref name="other"/> share at least one common element; otherwise, <c>false</c>.</returns>
+        public virtual bool Overlaps(IEnumerable<string> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (this.Count != 0)
+            {
+                foreach (var local in other)
+                {
+                    if (this.Contains(local))
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
 
-            foreach (var kvp in this.map)
+        /// <summary>
+        /// Determines whether the current <see cref="CharArraySet"/> object and a specified collection share common elements.
+        /// </summary>
+        /// <param name="other">The collection to compare to the current <see cref="CharArraySet"/> object.</param>
+        /// <returns><c>true</c> if the HashSet<T> object and <paramref name="other"/> share at least one common element; otherwise, <c>false</c>.</returns>
+        public virtual bool Overlaps<T>(IEnumerable<T> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (this.Count != 0)
             {
-                if (!otherSet.map.ContainsKey(kvp.Key))
+                foreach (var local in other)
+                {
+                    if (this.Contains(local))
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Returns <c>true</c> if this collection contains all of the elements
+        /// in the specified collection.
+        /// </summary>
+        /// <param name="other">collection to be checked for containment in this collection</param>
+        /// <returns><c>true</c> if this collection contains all of the elements in the specified collection; otherwise, <c>false</c>.</returns>
+        public virtual bool ContainsAll(IEnumerable<string> other)
+        {
+            foreach (var local in other)
+            {
+                if (!this.Contains(local))
+                {
                     return false;
+                }
+            }
+            return true;
+        }
 
-                if (!otherSet.map[kvp.Key].Equals(kvp.Value))
+        /// <summary>
+        /// Returns <c>true</c> if this collection contains all of the elements
+        /// in the specified collection.
+        /// </summary>
+        /// <param name="other">collection to be checked for containment in this collection</param>
+        /// <returns><c>true</c> if this collection contains all of the elements in the specified collection; otherwise, <c>false</c>.</returns>
+        public virtual bool ContainsAll<T>(IEnumerable<T> other)
+        {
+            foreach (var local in other)
+            {
+                if (!this.Contains(local))
+                {
                     return false;
+                }
             }
+            return true;
+        }
 
+        private bool IsSubsetOfCharArraySet(CharArraySet other)
+        {
+            foreach (var local in this)
+            {
+                if (!other.Contains(local))
+                {
+                    return false;
+                }
+            }
             return true;
         }
 
-        #region Not used by the Java implementation anyway
-        public void UnionWith(IEnumerable<object> other)
+        private void GetFoundAndUnfoundCounts<T>(IEnumerable<T> other, out int foundCount, out int unfoundCount)
+        {
+            foundCount = 0;
+            unfoundCount = 0;
+            foreach (var item in other)
+            {
+                if (this.Contains(item))
+                {
+                    foundCount++;
+                }
+                else
+                {
+                    unfoundCount++;
+                }
+            }
+        }
+
+        #endregion
+    }
+
+    /// <summary>
+    /// LUCENENET specific extension methods for CharArraySet
+    /// </summary>
+    public static class CharArraySetExtensions
+    {
+        #region Add
+
+        /// <summary>
+        /// Add this <see cref="bool"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, bool text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="byte"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, byte text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="char"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, char text)
+        {
+            return set.map.Put("" + text);
+        }
+
+        ///// <summary>
+        ///// Add this <see cref="decimal"/> into the set
+        ///// </summary>
+        ///// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        //public static bool Add(this CharArraySet set, decimal text)
+        //{
+        //    return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        //}
+
+        ///// <summary>
+        ///// Add this <see cref="double"/> into the set
+        ///// </summary>
+        ///// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        //public static bool Add(this CharArraySet set, double text)
+        //{
+        //    return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        //}
+
+        ///// <summary>
+        ///// Add this <see cref="float"/> into the set
+        ///// </summary>
+        ///// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        //public static bool Add(this CharArraySet set, float text)
+        //{
+        //    return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        //}
+
+        /// <summary>
+        /// Add this <see cref="int"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, int text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="long"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, long text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="sbyte"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, sbyte text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="short"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, short text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="uint"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, uint text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="ulong"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, ulong text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Add this <see cref="ushort"/> into the set
+        /// </summary>
+        /// <returns><c>true</c> if <paramref name="o"/> was added to the set; <c>false</c> if it already existed prior to this call</returns>
+        public static bool Add(this CharArraySet set, ushort text)
+        {
+            return set.map.Put(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        #endregion
+
+        #region Contains
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="bool"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, bool text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="byte"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, byte text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="char"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, char text)
+        {
+            return set.map.ContainsKey("" + text);
+        }
+
+        ///// <summary>
+        ///// <c>true</c> if the <see cref="decimal"/> is in the set
+        ///// </summary>
+        //public static bool Contains(this CharArraySet set, decimal text)
+        //{
+        //    return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        //}
+
+        ///// <summary>
+        ///// <c>true</c> if the <see cref="double"/> is in the set
+        ///// </summary>
+        //public static bool Contains(this CharArraySet set, double text)
+        //{
+        //    return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        //}
+
+        ///// <summary>
+        ///// <c>true</c> if the <see cref="float"/> is in the set
+        ///// </summary>
+        //public static bool Contains(this CharArraySet set, float text)
+        //{
+        //    return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        //}
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="int"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, int text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="long"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, long text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="sbyte"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, sbyte text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="short"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, short text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="uint"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, uint text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="ulong"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, ulong text)
+        {
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// <c>true</c> if the <see cref="ushort"/> is in the set
+        /// </summary>
+        public static bool Contains(this CharArraySet set, ushort text)
         {
-            throw new System.NotImplementedException();
+            return set.map.ContainsKey(text.ToString(CultureInfo.InvariantCulture));
+        }
+
+        #endregion
+
+        #region UnionWith
+
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<byte> other)
+        {
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public void IntersectWith(IEnumerable<object> other)
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<char> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add("" + item))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public void ExceptWith(IEnumerable<object> other)
+        ///// <summary>
+        ///// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        ///// in itself, the specified collection, or both.
+        ///// </summary>
+        ///// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        ///// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        //public static bool UnionWith(this CharArraySet set, IEnumerable<decimal> other)
+        //{
+        //    if (other == null)
+        //    {
+        //        throw new ArgumentNullException("other");
+        //    }
+        //    if (set.IsReadOnly)
+        //    {
+        //        throw new InvalidOperationException("CharArraySet is readonly");
+        //    }
+        //    bool modified = false;
+        //    foreach (var item in other)
+        //    {
+        //        if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+        //        {
+        //            modified = true;
+        //        }
+        //    }
+        //    return modified;
+        //}
+
+        ///// <summary>
+        ///// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        ///// in itself, the specified collection, or both.
+        ///// </summary>
+        ///// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        ///// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        //public static bool UnionWith(this CharArraySet set, IEnumerable<double> other)
+        //{
+        //    if (other == null)
+        //    {
+        //        throw new ArgumentNullException("other");
+        //    }
+        //    if (set.IsReadOnly)
+        //    {
+        //        throw new InvalidOperationException("CharArraySet is readonly");
+        //    }
+        //    bool modified = false;
+        //    foreach (var item in other)
+        //    {
+        //        if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+        //        {
+        //            modified = true;
+        //        }
+        //    }
+        //    return modified;
+        //}
+
+        ///// <summary>
+        ///// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        ///// in itself, the specified collection, or both.
+        ///// </summary>
+        ///// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        ///// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        //public static bool UnionWith(this CharArraySet set, IEnumerable<float> other)
+        //{
+        //    if (other == null)
+        //    {
+        //        throw new ArgumentNullException("other");
+        //    }
+        //    if (set.IsReadOnly)
+        //    {
+        //        throw new InvalidOperationException("CharArraySet is readonly");
+        //    }
+        //    bool modified = false;
+        //    foreach (var item in other)
+        //    {
+        //        if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+        //        {
+        //            modified = true;
+        //        }
+        //    }
+        //    return modified;
+        //}
+
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<int> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public void SymmetricExceptWith(IEnumerable<object> other)
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<long> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public bool IsSubsetOf(IEnumerable<object> other)
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<sbyte> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public bool IsSupersetOf(IEnumerable<object> other)
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<short> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public bool IsProperSupersetOf(IEnumerable<object> other)
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<uint> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public bool IsProperSubsetOf(IEnumerable<object> other)
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<ulong> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
-        public bool Overlaps(IEnumerable<object> other)
+        /// <summary>
+        /// Modifies the current <see cref="CharArraySet"/> to contain all elements that are present 
+        /// in itself, the specified collection, or both.
+        /// </summary>
+        /// <param name="other">The collection whose elements should be merged into the <see cref="CharArraySet"/>.</param>
+        /// <returns><c>true</c> if this <see cref="CharArraySet"/> changed as a result of the call</returns>
+        public static bool UnionWith(this CharArraySet set, IEnumerable<ushort> other)
         {
-            throw new System.NotImplementedException();
+            if (other == null)
+            {
+                throw new ArgumentNullException("other");
+            }
+            if (set.IsReadOnly)
+            {
+                throw new InvalidOperationException("CharArraySet is readonly");
+            }
+            bool modified = false;
+            foreach (var item in other)
+            {
+                if (set.Add(item.ToString(CultureInfo.InvariantCulture)))
+                {
+                    modified = true;
+                }
+            }
+            return modified;
         }
 
         #endregion

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/87d05125/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestBugInSomething.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestBugInSomething.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestBugInSomething.cs
index 42994be..6e093d9 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestBugInSomething.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestBugInSomething.cs
@@ -332,7 +332,7 @@ namespace Lucene.Net.Analysis.Core
         [Test]
         public virtual void TestCuriousWikipediaString()
         {
-            CharArraySet protWords = new CharArraySet(TEST_VERSION_CURRENT, new HashSet<object>(Arrays.AsList("rrdpafa", "pupmmlu", "xlq", "dyy", "zqrxrrck", "o", "hsrlfvcha")), false);
+            CharArraySet protWords = new CharArraySet(TEST_VERSION_CURRENT, new HashSet<string>(Arrays.AsList("rrdpafa", "pupmmlu", "xlq", "dyy", "zqrxrrck", "o", "hsrlfvcha")), false);
             sbyte[] table = new sbyte[] { -57, 26, 1, 48, 63, -23, 55, -84, 18, 120, -97, 103, 58, 13, 84, 89, 57, -13, -63, 5, 28, 97, -54, -94, 102, -108, -5, 5, 46, 40, 43, 78, 43, -72, 36, 29, 124, -106, -22, -51, 65, 5, 31, -42, 6, -99, 97, 14, 81, -128, 74, 100, 54, -55, -25, 53, -71, -98, 44, 33, 86, 106, -42, 47, 115, -89, -18, -26, 22, -95, -43, 83, -125, 105, -104, -24, 106, -16, 126, 115, -105, 97, 65, -33, 57, 44, -1, 123, -68, 100, 13, -41, -64, -119, 0, 92, 94, -36, 53, -9, -102, -18, 90, 94, -26, 31, 71, -20 };
             Analyzer a = new AnalyzerAnonymousInnerClassHelper2(this, protWords, table);
             CheckAnalysisConsistency(Random(), a, false, "B\u28c3\ue0f8[ \ud800\udfc2 </p> jb");

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/87d05125/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs
index e2abe3d..218004c 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs
@@ -76,8 +76,7 @@ namespace Lucene.Net.Analysis.Util
         public virtual void TestMethods()
         {
             CharArrayMap<int?> cm = new CharArrayMap<int?>(TEST_VERSION_CURRENT, 2, false);
-            //Dictionary<string, int?> hm = new Dictionary<string, int?>();
-            Dictionary<object, int?> hm = new Dictionary<object, int?>(); // TODO: In .NET, we cannot implicitly convert from string to object using generics
+            Dictionary<string, int?> hm = new Dictionary<string, int?>();
             hm["foo"] = 1;
             hm["bar"] = 2;
             cm.PutAll(hm);
@@ -86,25 +85,22 @@ namespace Lucene.Net.Analysis.Util
             cm.PutAll(hm);
             assertEquals(hm.Count, cm.Count);
 
-            // TODO: In .NET we cannot make this conversion implicitly.
+            // LUCENENET: Need to cast here - no implicit conversion.
             CharArraySet cs = cm.Keys as CharArraySet;
             int n = 0;
-            foreach (object o in cs)
+            foreach (string o in cs)
             {
                 assertTrue(cm.ContainsKey(o));
-                char[] co = (char[])o;
+                char[] co = o.ToCharArray();
                 assertTrue(cm.ContainsKey(co, 0, co.Length));
                 n++;
             }
             assertEquals(hm.Count, n);
             assertEquals(hm.Count, cs.Count);
             assertEquals(cm.Count, cs.Count);
-
-            // TODO: This directly contradicts the TestModifyOnUnmodifiable test,
-            // where clear is not allowed from the Keys property.
-            //cs.Clear();
-            //assertEquals(0, cs.Count);
-            //assertEquals(0, cm.Count);
+            cs.Clear();
+            assertEquals(0, cs.Count);
+            assertEquals(0, cm.Count);
             try
             {
                 cs.Add("test");
@@ -117,19 +113,18 @@ namespace Lucene.Net.Analysis.Util
             cm.PutAll(hm);
             assertEquals(hm.Count, cs.Count);
             assertEquals(cm.Count, cs.Count);
-
-            IEnumerator<KeyValuePair<object, int?>> iter1 = IDictionaryExtensions.EntrySet(cm).GetEnumerator();
+            // LUCENENET: Need to cast here - no implicit conversion
+            IEnumerator<KeyValuePair<string, int?>> iter1 = (IEnumerator<KeyValuePair<string, int?>>)cm.EntrySet().GetEnumerator();
             n = 0;
             while (iter1.MoveNext())
             {
-                KeyValuePair<object, int?> entry = iter1.Current;
+                KeyValuePair<string, int?> entry = iter1.Current;
                 object key = entry.Key;
                 int? val = entry.Value;
                 assertEquals(cm.Get(key), val);
-
-                // TODO: In .NET the Value property of KeyValuePair is read-only. Do we need a solution?
-                //entry.Value = val * 100;
-                //assertEquals(val * 100, (int)cm.Get(key));
+                // LUCENENET: Need a cast to get to this method because it is not part of the IEnumerator<T> interface
+                ((CharArrayMap<int?>.EntryIterator)iter1).SetValue(val * 100);
+                assertEquals(val * 100, (int)cm.Get(key));
                 n++;
             }
             assertEquals(hm.Count, n);
@@ -141,20 +136,16 @@ namespace Lucene.Net.Analysis.Util
             n = 0;
             while (iter2.MoveNext())
             {
-                char[] keyc = (char[])iter2.Current.Key;
+                var keyc = iter2.Current.Key;
                 int? val = iter2.Current.Value;
-                assertEquals(hm[new string(keyc)], val);
-
-                // TODO: In .NET the Value property of KeyValuePair is read-only. Do we need a solution?
-                //iter2.Value = val * 100;
-                //assertEquals(val * 100, (int)cm.Get(keyc));
+                assertEquals(hm[keyc], val);
+                iter2.SetValue(val * 100);
+                assertEquals(val * 100, (int)cm.Get(keyc));
                 n++;
             }
             assertEquals(hm.Count, n);
 
-            // TODO: In .NET, the EntrySet extension method makes a copy of the data
-            // so clearing it won't work like this.
-            cm.EntrySet().clear();
+            cm.EntrySet().Clear();
             assertEquals(0, cm.size());
             assertEquals(0, cm.EntrySet().size());
             assertTrue(cm.Count == 0);
@@ -173,7 +164,7 @@ namespace Lucene.Net.Analysis.Util
             assertTrue(map.ContainsKey("bar"));
             assertEquals(2, map.Get("bar"));
 
-            map = CharArrayMap<int?>.UnmodifiableMap(map);
+            map = CharArrayMap.UnmodifiableMap(map);
             assertEquals("Map size changed due to unmodifiableMap call", size, map.Count);
             var NOT_IN_MAP = "SirGallahad";
             assertFalse("Test String already exists in map", map.ContainsKey(NOT_IN_MAP));
@@ -221,7 +212,7 @@ namespace Lucene.Net.Analysis.Util
             #region Added for better .NET support
             try
             {
-                map.Add(new StringBuilder(NOT_IN_MAP), 3);
+                map.Add(NOT_IN_MAP, 3);
                 fail("Modified unmodifiable map");
             }
             catch (System.NotSupportedException)
@@ -234,7 +225,7 @@ namespace Lucene.Net.Analysis.Util
 
             try
             {
-                map.Add(new KeyValuePair<object, int?>(NOT_IN_MAP, 3));
+                map.Add(new KeyValuePair<string, int?>(NOT_IN_MAP, 3));
                 fail("Modified unmodifiable map");
             }
             catch (System.NotSupportedException)
@@ -260,7 +251,9 @@ namespace Lucene.Net.Analysis.Util
 
             try
             {
-                map.Remove(new KeyValuePair<object, int?>("foo", 1));
+#pragma warning disable 612, 618
+                map.Remove(new KeyValuePair<string, int?>("foo", 1));
+#pragma warning restore 612, 618
                 fail("Modified unmodifiable map");
             }
             catch (System.NotSupportedException)
@@ -316,19 +309,18 @@ namespace Lucene.Net.Analysis.Util
                 assertEquals("Size of unmodifiable map has changed", size, map.size());
             }
 
-            // TODO: In .NET we don't have an overload of PutAll that will convert this.
-            //try
-            //{
-            //    map.PutAll<string, int>(Collections.SingletonMap(NOT_IN_MAP, 3));
-            //    fail("Modified unmodifiable map");
-            //}
-            //catch (System.NotSupportedException)
-            //{
-            //    // expected
-            //    assertFalse("Test String has been added to unmodifiable map", map.ContainsKey(NOT_IN_MAP));
-            //    assertNull("Test String has been added to unmodifiable map", map.Get(NOT_IN_MAP));
-            //    assertEquals("Size of unmodifiable map has changed", size, map.size());
-            //}
+            try
+            {
+                map.PutAll(Collections.SingletonMap<string, int?>(NOT_IN_MAP, 3));
+                fail("Modified unmodifiable map");
+            }
+            catch (System.NotSupportedException)
+            {
+                // expected
+                assertFalse("Test String has been added to unmodifiable map", map.ContainsKey(NOT_IN_MAP));
+                assertNull("Test String has been added to unmodifiable map", map.Get(NOT_IN_MAP));
+                assertEquals("Size of unmodifiable map has changed", size, map.size());
+            }
 
             assertTrue(map.ContainsKey("foo"));
             assertEquals(1, map.Get("foo"));
@@ -339,14 +331,14 @@ namespace Lucene.Net.Analysis.Util
         [Test]
         public virtual void TestToString()
         {
-            CharArrayMap<int?> cm = new CharArrayMap<int?>(TEST_VERSION_CURRENT, Collections.SingletonMap<object, int?>("test", 1), false);
+            CharArrayMap<int?> cm = new CharArrayMap<int?>(TEST_VERSION_CURRENT, Collections.SingletonMap<string, int?>("test", 1), false);
             assertEquals("[test]", cm.Keys.ToString());
-            //assertEquals("[1]", cm.Values.ToString()); // TODO: In .NET it would not be possible to make a generic type override the ToString() method to customize it like this without wrapping the result.
+            assertEquals("[1]", cm.Values.ToString());
             assertEquals("[test=1]", cm.EntrySet().ToString());
             assertEquals("{test=1}", cm.ToString());
             cm.Put("test2", 2);
-            assertTrue(cm.Keys.ToString().Contains(", ")); // NOTE: See the note in the KeySet() method as for why this test fails.
-            //assertTrue(cm.Values.ToString().Contains(", ")); // TODO: In .NET it would not be possible to make a generic type override the ToString() method to customize it like this without wrapping the result.
+            assertTrue(cm.Keys.ToString().Contains(", "));
+            assertTrue(cm.Values.ToString().Contains(", "));
             assertTrue(cm.EntrySet().ToString().Contains(", "));
             assertTrue(cm.ToString().Contains(", "));
         }