edit: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/hash/equal_value_tags.txt;C1086571
File: equal_value_tags.txt
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/hash/equal_value_tags.txt;C1086571  (server)    2/4/2010 3:43 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/hash/equal_value_tags.txt;Equality
@@ -1,2 +1,2 @@
-critical:Hash#== computes equality for complex recursive hashes
+fails:Hash#== computes equality for complex recursive hashes
 fails:Hash#== computes equality for recursive hashes & arrays
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/struct/equal_value_tags.txt;C1473028
File: equal_value_tags.txt
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/struct/equal_value_tags.txt;C1473028  (server)    2/4/2010 3:59 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/struct/equal_value_tags.txt;Equality
@@ -1,1 +1,1 @@
-critical:Struct#== handles recursive structures by returning false if a difference can be found
+fails:Struct#== handles recursive structures by returning false if a difference can be found
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/array/equal_value_spec.rb;C1086571
File: equal_value_spec.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/array/equal_value_spec.rb;C1086571  (server)    2/4/2010 3:15 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/array/equal_value_spec.rb;Equality
@@ -26,6 +26,19 @@
     [obj].should == [5]
   end
 
+  it "returns obj == self if obj responds to to_ary" do
+    obj = Object.new
+
+    # String#== merely checks if #to_str is defined by calling respond_to?(:to_ary)
+    # It does not call to_ary.
+    obj.should_receive(:respond_to?).with(:to_ary).and_return(true)
+
+    # result will be converted to Boolean
+    obj.should_receive(:==).and_return(1)
+    
+    ([] == obj).should == true
+  end
+
   # As per bug #1720
   it "returns false for [NaN] == [NaN]" do
     [nan_value].should_not == [nan_value]
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/hash/equal_value_spec.rb;C1086571
File: equal_value_spec.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/hash/equal_value_spec.rb;C1086571  (server)    2/4/2010 3:14 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/hash/equal_value_spec.rb;Equality
@@ -10,4 +10,18 @@
   it "compares values with == semantics" do
     new_hash("x" => 1.0).should == new_hash("x" => 1)
   end
+
+  it "returns obj == self if obj responds to to_hash" do
+    obj = Object.new
+
+    # String#== merely checks if #to_str is defined by calling respond_to?(:to_hash)
+    # It does not call to_hash.
+    obj.should_receive(:respond_to?).with(:to_hash).and_return(true)
+
+    # result will be converted to Boolean
+    obj.should_receive(:==).and_return(1)
+
+    h = {}
+    (h == obj).should == true
+  end
 end
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/string/equal_value_spec.rb;C1473028
File: equal_value_spec.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/string/equal_value_spec.rb;C1473028  (server)    2/4/2010 3:12 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/string/equal_value_spec.rb;Equality
@@ -16,13 +16,14 @@
   it "returns obj == self if obj responds to to_str" do
     obj = Object.new
 
-    # String#== merely checks if #to_str is defined. It does
-    # not call it.
-    obj.stub!(:to_str)
+    # String#== merely checks if #to_str is defined by calling respond_to?(:to_str)
+    # It does not call to_str.
+    obj.should_receive(:respond_to?).with(:to_str).and_return(true)
 
-    obj.should_receive(:==).and_return(true)
+    # result will be converted to Boolean
+    obj.should_receive(:==).and_return(1)
 
-    ('hello' == obj).should ==  true
+    ('hello' == obj).should == true
   end
 
   it "is not fooled by NUL characters" do
===================================================================
add: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Recursion
add: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Recursion/recursion.rb
File: recursion.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Experimental/Recursion/recursion.rb;Equality
@@ -1,0 +1,50 @@
+#  
+# MRI has only one RecursionTracker (we have one per operation kind).
+# Thus if we inspect an array while comparison with another recursive array is in progress we get [...] in MRI.
+#
+
+class C
+  @@a = 0
+
+  def initialize
+    @a = @@a
+    @@a += 1    
+  end
+  
+  def ==(other)
+    puts "#@a == #{other.instance_variable_get(:@a)}"
+    
+    p $a
+    p $a == $b
+    
+    true
+  end
+end
+
+$a = Array.new([C.new,C.new,C.new])
+$a << $a
+
+$b = Array.new([C.new,C.new,C.new])
+$b << $b
+
+p $a == $b
+
+=begin
+S = Struct.new(:f,:g)
+s = S[1,2]
+s2 = S[1,2]
+
+a = []
+b = {1 => a}
+a << s
+s.f = b
+s.g = a
+
+a2 = []
+b2 = {1 => a2}
+a2 << s2
+s2.f = b
+s2.g = a
+
+p b2 == b
+=end
\ No newline at end of file
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C1546541
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C1546541  (server)    2/4/2010 3:27 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;Equality
@@ -1831,8 +1831,8 @@
             );
             
             DefineLibraryMethod(module, "each", 0x51, 
-                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, IronRuby.Builtins.MutableString, System.Object>(IronRuby.Builtins.RubyIOOps.Each), 
-                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, System.Object>(IronRuby.Builtins.RubyIOOps.Each)
+                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, System.Object>(IronRuby.Builtins.RubyIOOps.Each), 
+                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, IronRuby.Builtins.MutableString, System.Object>(IronRuby.Builtins.RubyIOOps.Each)
             );
             
             DefineLibraryMethod(module, "each_byte", 0x51, 
@@ -1840,8 +1840,8 @@
             );
             
             DefineLibraryMethod(module, "each_line", 0x51, 
-                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, IronRuby.Builtins.MutableString, System.Object>(IronRuby.Builtins.RubyIOOps.Each), 
-                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, System.Object>(IronRuby.Builtins.RubyIOOps.Each)
+                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, System.Object>(IronRuby.Builtins.RubyIOOps.Each), 
+                new Func<IronRuby.Runtime.RubyContext, IronRuby.Runtime.BlockParam, IronRuby.Builtins.RubyIO, IronRuby.Builtins.MutableString, System.Object>(IronRuby.Builtins.RubyIOOps.Each)
             );
             
             DefineLibraryMethod(module, "eof", 0x51, 
@@ -3180,10 +3180,10 @@
             );
             
             DefineLibraryMethod(module, "puts", 0x52, 
-                new Action<IronRuby.Runtime.BinaryOpStorage, System.Object>(IronRuby.Builtins.KernelOps.PutsEmptyLine), 
-                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object>(IronRuby.Builtins.KernelOps.PutString), 
                 new Action<IronRuby.Runtime.BinaryOpStorage, System.Object, IronRuby.Builtins.MutableString>(IronRuby.Builtins.KernelOps.PutString), 
-                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object[]>(IronRuby.Builtins.KernelOps.PutString)
+                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object[]>(IronRuby.Builtins.KernelOps.PutString), 
+                new Action<IronRuby.Runtime.BinaryOpStorage, System.Object>(IronRuby.Builtins.KernelOps.PutsEmptyLine), 
+                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object>(IronRuby.Builtins.KernelOps.PutString)
             );
             
             DefineLibraryMethod(module, "raise", 0x52, 
@@ -3483,10 +3483,10 @@
             );
             
             DefineLibraryMethod(module, "puts", 0x61, 
+                new Action<IronRuby.Runtime.BinaryOpStorage, System.Object, IronRuby.Builtins.MutableString>(IronRuby.Builtins.KernelOps.PutString), 
+                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object[]>(IronRuby.Builtins.KernelOps.PutString), 
                 new Action<IronRuby.Runtime.BinaryOpStorage, System.Object>(IronRuby.Builtins.KernelOps.PutsEmptyLine), 
-                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object>(IronRuby.Builtins.KernelOps.PutString), 
-                new Action<IronRuby.Runtime.BinaryOpStorage, System.Object, IronRuby.Builtins.MutableString>(IronRuby.Builtins.KernelOps.PutString), 
-                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object[]>(IronRuby.Builtins.KernelOps.PutString)
+                new Action<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.ConversionStorage<IronRuby.Builtins.MutableString>, IronRuby.Runtime.ConversionStorage<System.Collections.IList>, System.Object, System.Object>(IronRuby.Builtins.KernelOps.PutString)
             );
             
             DefineLibraryMethod(module, "raise", 0x61, 
@@ -5431,7 +5431,12 @@
             );
             
             DefineLibraryMethod(module, "==", 0x51, 
-                new Func<IronRuby.Runtime.BinaryOpStorage, System.Collections.Generic.IDictionary<System.Object, System.Object>, System.Object, System.Boolean>(IronRuby.Builtins.IDictionaryOps.Equals)
+                new Func<IronRuby.Runtime.RespondToStorage, IronRuby.Runtime.BinaryOpStorage, System.Collections.Generic.IDictionary<System.Object, System.Object>, System.Object, System.Boolean>(IronRuby.Builtins.IDictionaryOps.Equals), 
+                new Func<IronRuby.Runtime.BinaryOpStorage, System.Collections.Generic.IDictionary<System.Object, System.Object>, System.Collections.Generic.IDictionary<System.Object, System.Object>, System.Boolean>(IronRuby.Builtins.IDictionaryOps.Equals)
+            );
+            
+            DefineLibraryMethod(module, "===", 0x51, 
+                new Func<IronRuby.Runtime.RespondToStorage, IronRuby.Runtime.BinaryOpStorage, System.Collections.Generic.IDictionary<System.Object, System.Object>, System.Object, System.Boolean>(IronRuby.Builtins.IDictionaryOps.Equals)
             );
             
             DefineLibraryMethod(module, "clear", 0x51, 
@@ -5652,7 +5657,7 @@
             );
             
             DefineLibraryMethod(module, "==", 0x51, 
-                new Func<IronRuby.Runtime.ConversionStorage<System.Collections.IList>, IronRuby.Runtime.BinaryOpStorage, System.Collections.IList, System.Object, System.Boolean>(IronRuby.Builtins.IListOps.Equals), 
+                new Func<IronRuby.Runtime.RespondToStorage, IronRuby.Runtime.BinaryOpStorage, System.Collections.IList, System.Object, System.Boolean>(IronRuby.Builtins.IListOps.Equals), 
                 new Func<IronRuby.Runtime.BinaryOpStorage, System.Collections.IList, System.Collections.IList, System.Boolean>(IronRuby.Builtins.IListOps.Equals)
             );
             
@@ -8703,11 +8708,11 @@
             );
             
             DefineLibraryMethod(module, "<=>", 0x11, 
-                new Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, IronRuby.StandardLibrary.BigDecimal.BigDecimal, System.Object, System.Object>(IronRuby.StandardLibrary.BigDecimal.BigDecimalOps.Compare), 
                 new Func<IronRuby.StandardLibrary.BigDecimal.BigDecimal, IronRuby.StandardLibrary.BigDecimal.BigDecimal, System.Object>(IronRuby.StandardLibrary.BigDecimal.BigDecimalOps.Compare), 
                 new Func<IronRuby.Runtime.RubyContext, IronRuby.StandardLibrary.BigDecimal.BigDecimal, Microsoft.Scripting.Math.BigInteger, System.Object>(IronRuby.StandardLibrary.BigDecimal.BigDecimalOps.Compare), 
                 new Func<IronRuby.Runtime.RubyContext, IronRuby.StandardLibrary.BigDecimal.BigDecimal, System.Int32, System.Object>(IronRuby.StandardLibrary.BigDecimal.BigDecimalOps.Compare), 
-                new Func<IronRuby.Runtime.RubyContext, IronRuby.StandardLibrary.BigDecimal.BigDecimal, System.Double, System.Object>(IronRuby.StandardLibrary.BigDecimal.BigDecimalOps.Compare)
+                new Func<IronRuby.Runtime.RubyContext, IronRuby.StandardLibrary.BigDecimal.BigDecimal, System.Double, System.Object>(IronRuby.StandardLibrary.BigDecimal.BigDecimalOps.Compare), 
+                new Func<IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.BinaryOpStorage, IronRuby.StandardLibrary.BigDecimal.BigDecimal, System.Object, System.Object>(IronRuby.StandardLibrary.BigDecimal.BigDecimalOps.Compare)
             );
             
             DefineLibraryMethod(module, "==", 0x11, 
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C1496258
File: MutableStringOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C1496258  (server)    2/4/2010 3:22 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;Equality
@@ -469,6 +469,10 @@
             return lhs.Equals(rhs);
         }
 
+        /// <summary>
+        /// Checks if <paramref name="other"/> responds to <c>to_str</c> and if so calls <paramref name="other"/>.==(<paramref name="self"/>).
+        /// </summary>
+        /// <see cref="http://redmine.ruby-lang.org/repositories/revision/2?rev=3442"/>
         [RubyMethod("==")]
         [RubyMethod("===")]
         public static bool Equals(RespondToStorage/*!*/ respondToStorage, BinaryOpStorage/*!*/ equalsStorage,
@@ -479,8 +483,7 @@
                 return false;
             }
 
-            var equals = equalsStorage.GetCallSite("==");
-            return Protocols.IsTrue(equals.Target(equals, other, self));
+            return Protocols.IsEqual(equalsStorage, other, self);
         }
 
         #endregion
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StructOps.cs;C1496258
File: StructOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StructOps.cs;C1496258  (server)    2/4/2010 3:48 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StructOps.cs;Equality
@@ -202,7 +202,7 @@
         public static bool Equal(BinaryOpStorage/*!*/ eqlStorage, RubyStruct/*!*/ self, object other) {
             return self.Equals(eqlStorage, other);
         }
-
+        
         // same pattern as RubyStruct.Equals, but we need to call == instead of eql?
         [RubyMethod("==")]
         public static bool Equals(BinaryOpStorage/*!*/ equals, RubyStruct/*!*/ self, object obj) {
@@ -213,11 +213,17 @@
             Debug.Assert(self.ItemCount == other.ItemCount);
 
             if (self.Values.Length > 0) {
-                var site = equals.GetCallSite("==");
-                for (int i = 0; i < self.Values.Length; i++) {
-                    if (RubyOps.IsFalse(site.Target(site, self.Values[i], other.Values[i]))) {
+                using (IDisposable handle = RubyUtils.InfiniteEqualsTracker.TrackObject(self)) {
+                    if (handle == null) {
+                        // hashing of recursive array
                         return false;
                     }
+
+                    for (int i = 0; i < self.Values.Length; i++) {
+                        if (!Protocols.IsEqual(equals, self.Values[i], other.Values[i])) {
+                            return false;
+                        }
+                    }
                 }
             }
 
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C1116347
File: IDictionaryOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C1116347  (server)    2/4/2010 3:22 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;Equality
@@ -17,12 +17,13 @@
 using System.Collections;
 using System.Collections.Generic;
 using System.Reflection;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
+using Microsoft.Scripting;
 using Microsoft.Scripting.Runtime;
 using Microsoft.Scripting.Actions;
 using Microsoft.Scripting.Generation;
 using Microsoft.Scripting.Utils;
-using System.Runtime.CompilerServices;
 using IronRuby.Runtime;
 
 namespace IronRuby.Builtins {
@@ -71,20 +72,47 @@
 
         #region Instance Methods
 
+        /// <summary>
+        /// Checks if <paramref name="other"/> responds to <c>to_hash</c> and if so calls <paramref name="other"/>.==(<paramref name="self"/>).
+        /// </summary>
+        /// <see cref="http://redmine.ruby-lang.org/repositories/revision/2?rev=3442"/>
         [RubyMethod("==")]
-        public static bool Equals(BinaryOpStorage/*!*/ equals, IDictionary<object, object>/*!*/ self, object otherHash) {
-            IDictionary<object, object> other = otherHash as IDictionary<object, object>;
-            if (other == null || self.Count != other.Count) {
+        public static bool Equals(RespondToStorage/*!*/ respondToStorage, BinaryOpStorage/*!*/ equalsStorage,
+            IDictionary<object, object>/*!*/ self, object other) {
+
+            if (other == null || !Protocols.RespondTo(respondToStorage, other, "to_hash")) {
+                return false;
+            }
+
+            return Protocols.IsEqual(equalsStorage, other, self);
+        }
+
+        [RubyMethod("==")]
+        public static bool Equals(BinaryOpStorage/*!*/ equals, IDictionary<object, object>/*!*/ self, [NotNull]IDictionary<object, object>/*!*/ other) {
+            Assert.NotNull(self, other);
+
+            if (Object.ReferenceEquals(self, other)) {
+                return true;
+            }
+
+            if (self.Count != other.Count) {
                 return false;
             }
 
-            // Each key value pair must be the same
-            foreach (KeyValuePair<object, object> pair in self) {
-                object value;
-                if (!other.TryGetValue(pair.Key, out value) || !Protocols.IsEqual(equals, pair.Value, value)) {
+            using (IDisposable handle = RubyUtils.InfiniteEqualsTracker.TrackObject(self)) {
+                if (handle == null) {
+                    // hashing of recursive array
                     return false;
                 }
+
+                foreach (KeyValuePair<object, object> pair in self) {
+                    object value;
+                    if (!other.TryGetValue(pair.Key, out value) || !Protocols.IsEqual(equals, pair.Value, value)) {
+                        return false;
+                    }
+                }
             }
+
             return true;
         }
 
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;C1301388
File: IListOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;C1301388  (server)    2/4/2010 3:17 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;Equality
@@ -317,20 +317,26 @@
 
         #region ==, <=>, eql?, hash
 
+        /// <summary>
+        /// Checks if <paramref name="other"/> responds to <c>to_ary</c> and if so calls <paramref name="other"/>.==(<paramref name="self"/>).
+        /// </summary>
+        /// <see cref="http://redmine.ruby-lang.org/repositories/revision/2?rev=3442"/>
         [RubyMethod("==")]
-        public static bool Equals(ConversionStorage<IList>/*!*/ arrayTryConvert, BinaryOpStorage/*!*/ equals, IList/*!*/ self, object other) {
-            IList otherAsArray = Protocols.TryConvertToArray(arrayTryConvert, other);
-            return otherAsArray != null ? Equals(equals, self, otherAsArray) : false;
+        public static bool Equals(RespondToStorage/*!*/ respondToStorage, BinaryOpStorage/*!*/ equalsStorage,
+            IList/*!*/ self, object other) {
+
+            if (other == null || !Protocols.RespondTo(respondToStorage, other, "to_ary")) {
+                return false;
+            }
+
+            return Protocols.IsEqual(equalsStorage, other, self);
         }
 
-        [MultiRuntimeAware]
-        private static RubyUtils.RecursionTracker _EqualsTracker = new RubyUtils.RecursionTracker();
-
         [RubyMethod("==")]
         public static bool Equals(BinaryOpStorage/*!*/ equals, IList/*!*/ self, [NotNull]IList/*!*/ other) {
             Assert.NotNull(self, other);
 
-            if (object.ReferenceEquals(self, other)) {
+            if (Object.ReferenceEquals(self, other)) {
                 return true;
             }
 
@@ -338,7 +344,7 @@
                 return false;
             }
 
-            using (IDisposable handle = _EqualsTracker.TrackObject(self)) {
+            using (IDisposable handle = RubyUtils.InfiniteEqualsTracker.TrackObject(self)) {
                 if (handle == null) {
                     // hashing of recursive array
                     return false;
@@ -355,12 +361,9 @@
             return true;
         }
 
-        [MultiRuntimeAware]
-        private static RubyUtils.RecursionTracker _infiniteComparisonTracker = new RubyUtils.RecursionTracker();
-
         [RubyMethod("<=>")]
         public static object Compare(BinaryOpStorage/*!*/ comparisonStorage, IList/*!*/ self, [DefaultProtocol, NotNull]IList/*!*/ other) {
-            using (IDisposable handle = _infiniteComparisonTracker.TrackObject(self)) {
+            using (IDisposable handle = RubyUtils.InfiniteComparisonTracker.TrackObject(self)) {
                 if (handle == null) {
                     return 0;
                 }
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyArray.cs;C1496258
File: RubyArray.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyArray.cs;C1496258  (server)    2/4/2010 4:05 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyArray.cs;Equality
@@ -190,9 +190,6 @@
             return hash;
         }
 
-        [MultiRuntimeAware]
-        private static RubyUtils.RecursionTracker _EqualsTracker = new RubyUtils.RecursionTracker();
-
         public static bool Equals(BinaryOpStorage/*!*/ eqlStorage, IList/*!*/ self, object obj) {
             if (ReferenceEquals(self, obj)) {
                 return true;
@@ -203,7 +200,7 @@
                 return false;
             }
 
-            using (IDisposable handle = _EqualsTracker.TrackObject(self)) {
+            using (IDisposable handle = RubyUtils.InfiniteEqualsTracker.TrackObject(self)) {
                 if (handle == null) {
                     // hashing of recursive array
                     return false;
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C1546541
File: RubyUtils.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C1546541  (server)    2/4/2010 4:06 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;Equality
@@ -730,20 +730,34 @@
             }
         }
 
+        // MRI 1.8 seems to have an equivalent of only a single RecursionTracker (MRI 1.9 has one per operation kind like we do).
+        // Thus if we inspect an array while a comparison with another recursive array is in progress we get [...] in MRI 1.8.
+
         [MultiRuntimeAware]
         private static readonly RecursionTracker _infiniteInspectTracker = new RecursionTracker();
+        [MultiRuntimeAware]
+        private static readonly RecursionTracker _infiniteToSTracker = new RecursionTracker();
+        [MultiRuntimeAware]
+        private static readonly RubyUtils.RecursionTracker _infiniteEqualsTracker = new RubyUtils.RecursionTracker();
+        [MultiRuntimeAware]
+        private static readonly RubyUtils.RecursionTracker _infiniteComparisonTracker = new RubyUtils.RecursionTracker();
 
         public static RecursionTracker InfiniteInspectTracker {
             get { return _infiniteInspectTracker; }
         }
 
-        [MultiRuntimeAware]
-        private static readonly RecursionTracker _infiniteToSTracker = new RecursionTracker();
-
         public static RecursionTracker InfiniteToSTracker {
             get { return _infiniteToSTracker; }
         }
 
+        public static RecursionTracker InfiniteEqualsTracker {
+            get { return _infiniteEqualsTracker; }
+        }
+
+        public static RecursionTracker InfiniteComparisonTracker {
+            get { return _infiniteComparisonTracker; }
+        }
+
         #endregion
 
         #region Arrays, Hashes
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Interop/net/method/fixtures/classes.rb;C1237359
File: classes.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Interop/net/method/fixtures/classes.rb;C1237359  (server)    2/4/2010 4:54 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Interop/net/method/fixtures/classes.rb;Equality
@@ -1,5 +1,4 @@
 require File.dirname(__FILE__) + "/../../bcl/fixtures/classes"
-reference "System.dll"
 csc <<-EOL
 using Microsoft.Scripting.Math;
 using Microsoft.Scripting.Utils;
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Interop/tags/net/method/binding/collection_tags.txt;C1405890
File: collection_tags.txt
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Interop/tags/net/method/binding/collection_tags.txt;C1405890  (server)    2/4/2010 5:54 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Interop/tags/net/method/binding/collection_tags.txt;Equality
@@ -56,3 +56,9 @@
 fails:Method parameter binding for collections passes the correct input (Dictionary[Object,Object]Instance) into method (IDictionaryOfObjectObjectArg) (RubyClassWithMethods)
 fails:Method parameter binding for collections passes the correct input (Dictionary[Fixnum,String]InstanceEmpty) into method (IDictionaryOfIntStringArg) (ClassWithMethods)
 fails:Method parameter binding for collections passes the correct input (Dictionary[Fixnum,String]InstanceEmpty) into method (IDictionaryOfIntStringArg) (RubyClassWithMethods)
+fails:Method parameter binding for collections passes the correct input (CStructInstance) into method (ParamsCStructArrArg) (ClassWithMethods)
+fails:Method parameter binding for collections passes the correct input (CStructInstance) into method (ParamsCStructArrArg) (RubyClassWithMethods)
+fails:Method parameter binding for collections passes the correct input (Int32Instance) into method (ParamsInt32ArrArg) (ClassWithMethods)
+fails:Method parameter binding for collections passes the correct input (Int32Instance) into method (ParamsInt32ArrArg) (RubyClassWithMethods)
+fails:Method parameter binding for collections passes the correct input (IInterfaceInstance) into method (ParamsIInterfaceArrArg) (ClassWithMethods)
+fails:Method parameter binding for collections passes the correct input (IInterfaceInstance) into method (ParamsIInterfaceArrArg) (RubyClassWithMethods)
\ No newline at end of file
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Scripts/csc.rb;C1162008
File: csc.rb
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Scripts/csc.rb;C1162008  (server)    2/4/2010 5:16 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Tests/Scripts/csc.rb;Equality
@@ -62,6 +62,12 @@
     debug("reference", ref)
     Compiler.refs << ref.strip
   end
+  
+  def reference_clr2
+    Compiler.nostdlib
+    reference File.join(ENV['FrameworkDir'], 'v2.0.50727\\mscorlib.dll')
+    reference File.join(ENV['FrameworkDir'], 'v2.0.50727\\System.dll')
+  end
 end
 
 class Compiler
@@ -69,6 +75,7 @@
     @assemblies = {}
     @target_dir = target_dir
     @current = nil
+    @nostdlib = false
   end
 
   def self.create(target_dir)
@@ -90,7 +97,11 @@
   def refs
     @assemblies[@current].refs
   end
-
+  
+  def nostdlib
+    @assemblies[@current].nostdlib = true
+  end
+  
   def switch_to(name, options)
     unless @assemblies[name]
       @assemblies[name] = Assembly.new(@target_dir, options)
@@ -105,12 +116,13 @@
 end
 
 class Assembly
-  attr_accessor :code, :refs
+  attr_accessor :code, :refs, :nostdlib
   def initialize(target_dir,options)
     @target_dir = target_dir
     @options = options
     @code = []
     @refs = []
+    @nostdlib = false
   end
 
   def compile(name)
@@ -121,6 +133,9 @@
       if @options[:references]
         @refs << @options[:references]
       end
+      if @nostdlib
+        opts << " /nostdlib"
+      end
       if @options[:target]
         opts << " /t:#{@options[:target]}"
       end
@@ -130,9 +145,9 @@
       @refs.each do |ref|
         opts << " /r:#{ref}"
       end
-      cmd = "csc /t:library /noconfig#{opts} #{name}"
+      cmd = "csc /nologo /t:library /noconfig#{opts} #{name}"
       debug("compile", cmd)
-      system cmd
+      puts system(cmd) ? 'ok' : 'error'      
     end
   end
 end
===================================================================
