Revert "THRIFT-4982 Remove deprecated C# bindings from the code base"

Only compiler, test, lib and tutorial code.
diff --git a/lib/csharp/src/Collections/TCollections.cs b/lib/csharp/src/Collections/TCollections.cs
new file mode 100644
index 0000000..84afb6a
--- /dev/null
+++ b/lib/csharp/src/Collections/TCollections.cs
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections;
+
+namespace Thrift.Collections
+{
+    public class TCollections
+    {
+        /// <summary>
+        /// This will return true if the two collections are value-wise the same.
+        /// If the collection contains a collection, the collections will be compared using this method.
+        /// </summary>
+        public static bool Equals (IEnumerable first, IEnumerable second)
+        {
+            if (first == null && second == null)
+            {
+                return true;
+            }
+            if (first == null || second == null)
+            {
+                return false;
+            }
+            IEnumerator fiter = first.GetEnumerator ();
+            IEnumerator siter = second.GetEnumerator ();
+
+            bool fnext = fiter.MoveNext ();
+            bool snext = siter.MoveNext ();
+            while (fnext && snext)
+            {
+                IEnumerable fenum = fiter.Current as IEnumerable;
+                IEnumerable senum = siter.Current as IEnumerable;
+                if (fenum != null && senum != null)
+                {
+                    if (!Equals(fenum, senum))
+                    {
+                        return false;
+                    }
+                }
+                else if (fenum == null ^ senum == null)
+                {
+                    return false;
+                }
+                else if (!Equals(fiter.Current, siter.Current))
+                {
+                    return false;
+                }
+                fnext = fiter.MoveNext();
+                snext = siter.MoveNext();
+            }
+
+            return fnext == snext;
+        }
+
+        /// <summary>
+        /// This returns a hashcode based on the value of the enumerable.
+        /// </summary>
+        public static int GetHashCode (IEnumerable enumerable)
+        {
+            if (enumerable == null)
+            {
+                return 0;
+            }
+
+            int hashcode = 0;
+            foreach (object obj in enumerable)
+            {
+                IEnumerable enum2 = obj as IEnumerable;
+                int objHash = enum2 == null ? obj.GetHashCode () : GetHashCode (enum2);
+                unchecked
+                {
+                    hashcode = (hashcode * 397) ^ (objHash);
+                }
+            }
+            return hashcode;
+        }
+    }
+}
diff --git a/lib/csharp/src/Collections/THashSet.cs b/lib/csharp/src/Collections/THashSet.cs
new file mode 100644
index 0000000..e29271a
--- /dev/null
+++ b/lib/csharp/src/Collections/THashSet.cs
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+#if SILVERLIGHT
+using System.Runtime.Serialization;
+#endif
+
+namespace Thrift.Collections
+{
+#if SILVERLIGHT
+    [DataContract]
+#else
+    [Serializable]
+#endif
+    public class THashSet<T> : ICollection<T>
+    {
+#if NET_2_0 || SILVERLIGHT
+#if SILVERLIGHT
+        [DataMember]
+#endif
+        TDictSet<T> set = new TDictSet<T>();
+#else
+        HashSet<T> set = new HashSet<T>();
+#endif
+        public int Count
+        {
+            get { return set.Count; }
+        }
+
+        public bool IsReadOnly
+        {
+            get { return false; }
+        }
+
+        public void Add(T item)
+        {
+            set.Add(item);
+        }
+
+        public void Clear()
+        {
+            set.Clear();
+        }
+
+        public bool Contains(T item)
+        {
+            return set.Contains(item);
+        }
+
+        public void CopyTo(T[] array, int arrayIndex)
+        {
+            set.CopyTo(array, arrayIndex);
+        }
+
+        public IEnumerator GetEnumerator()
+        {
+            return set.GetEnumerator();
+        }
+
+        IEnumerator<T> IEnumerable<T>.GetEnumerator()
+        {
+            return ((IEnumerable<T>)set).GetEnumerator();
+        }
+
+        public bool Remove(T item)
+        {
+            return set.Remove(item);
+        }
+
+#if NET_2_0 || SILVERLIGHT
+#if SILVERLIGHT
+        [DataContract]
+#endif
+        private class TDictSet<V> : ICollection<V>
+        {
+#if SILVERLIGHT
+            [DataMember]
+#endif
+            Dictionary<V, TDictSet<V>> dict = new Dictionary<V, TDictSet<V>>();
+
+            public int Count
+            {
+                get { return dict.Count; }
+            }
+
+            public bool IsReadOnly
+            {
+                get { return false; }
+            }
+
+            public IEnumerator GetEnumerator()
+            {
+                return ((IEnumerable)dict.Keys).GetEnumerator();
+            }
+
+            IEnumerator<V> IEnumerable<V>.GetEnumerator()
+            {
+                return dict.Keys.GetEnumerator();
+            }
+
+            public bool Add(V item)
+            {
+                if (!dict.ContainsKey(item))
+                {
+                    dict[item] = this;
+                    return true;
+                }
+
+                return false;
+            }
+
+            void ICollection<V>.Add(V item)
+            {
+                Add(item);
+            }
+
+            public void Clear()
+            {
+                dict.Clear();
+            }
+
+            public bool Contains(V item)
+            {
+                return dict.ContainsKey(item);
+            }
+
+            public void CopyTo(V[] array, int arrayIndex)
+            {
+                dict.Keys.CopyTo(array, arrayIndex);
+            }
+
+            public bool Remove(V item)
+            {
+                return dict.Remove(item);
+            }
+        }
+#endif
+    }
+
+}