edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C653141
File: RubyTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C653141  (server)    11/24/2008 10:54 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;RubyClrInterop06
@@ -316,6 +316,8 @@
                 ClrDelegates2,
                 ClrEvents1,
                 ClrOverride1,
+                ClrConstructor1,
+                // TODO: ClrConstructor2,
                 Scenario_RubyEngine1,
                 Scenario_RubyInteractive,
                 
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ClrTests.cs;C642953
File: ClrTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ClrTests.cs;C642953  (server)    11/24/2008 10:45 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ClrTests.cs;RubyClrInterop06
@@ -15,6 +15,9 @@
 
 using System;
 using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.Serialization;
 using Microsoft.Scripting.Runtime;
 using IronRuby.Runtime;
 using IronRuby.Builtins;
@@ -509,5 +512,53 @@
 RM1CM2CP1CP2RP3
 ");
         }
+
+        public class ClassWithNonEmptyConstructor {
+            public string P { get; set; }
+            public ClassWithNonEmptyConstructor() {
+            }
+            public ClassWithNonEmptyConstructor(string p) {
+                P = p;
+            }
+        }
+
+        private static bool IsAvailable(MethodBase method) {
+            return method != null && !method.IsPrivate && !method.IsFamilyAndAssembly;
+        }
+
+        public void ClrConstructor1() {
+            Context.ObjectClass.SetConstant("C", Context.GetClass(typeof(ClassWithNonEmptyConstructor)));
+            var cls = Engine.Execute(@"
+class D < C; end
+D.new
+D
+");
+            var rubyClass = (cls as RubyClass);
+            Debug.Assert(rubyClass != null);
+
+            Type baseType = rubyClass.GetUnderlyingSystemType();
+            Assert(IsAvailable(baseType.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(RubyClass) }, null)));
+            Assert(IsAvailable(baseType.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(RubyClass), typeof(string) }, null)));
+#if !SILVERLIGHT
+            Assert(IsAvailable(baseType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] {
+                typeof(SerializationInfo), typeof(StreamingContext) }, null)));
+#endif
+        }
+
+        public void ClrConstructor2() {
+            // TODO: Requires allocator support
+            Context.ObjectClass.SetConstant("C", Context.GetClass(typeof(ClassWithNonEmptyConstructor)));
+            AssertOutput(delegate() {
+                CompilerTest(@"
+class D < C; end
+
+$d = D.new 'test'
+puts $d.p
+");
+            }, @"
+test
+");
+        }
+
     }
 }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/RubyTypeBuilder.cs;C653141
File: RubyTypeBuilder.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/RubyTypeBuilder.cs;C653141  (server)    11/24/2008 10:56 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/RubyTypeBuilder.cs;RubyClrInterop06
@@ -14,6 +14,7 @@
  * ***************************************************************************/
 
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
 using System.Dynamic.Binders;
 using System.Reflection;
@@ -102,77 +103,107 @@
 
         private void DefineConstructors() {
             BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
+            ConstructorInfo emptyCtor = _tb.BaseType.GetConstructor(bindingFlags, null, Type.EmptyTypes, null);
 
-            // ctor(RubyClass! class) : ... { this._class = class; } 
-            ConstructorBuilder ctor = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,
-                new Type[] { typeof(RubyClass) }
-            );
-            ILGen il = new ILGen(ctor.GetILGenerator());
+            bool deserializerFound = false;
+            foreach (var baseCtor in _tb.BaseType.GetConstructors(bindingFlags)) {
+                int oldLength = baseCtor.GetParameters().Length;
+                List<Type> newParams = new List<Type>(oldLength + 1);
+                foreach (var param in baseCtor.GetParameters()) {
+                    newParams.Add(param.ParameterType);
+                }
 
-            ConstructorInfo baseCtor;
+                int startPos = 2;
+                bool isDeserializer = false;
+                if (oldLength > 0 && newParams[0] == typeof(RubyClass)) {
+                    // Build a simple pass-through constructor
+                    startPos = 1;
+#if !SILVERLIGHT
+                } else if (oldLength == 2 && newParams[0] == typeof(SerializationInfo) && newParams[1] == typeof(StreamingContext)) {
+                    // Build a deserializer
+                    deserializerFound = true;
+                    isDeserializer = true;
+#endif
+                } else {
+                    // Special-case for Exception
+                    if (_tb.IsSubclassOf(typeof(Exception)) && IsAvailable(emptyCtor)) {
+                        if (oldLength == 0) {
+                            // Skip this constructor; it would conflict with the one we're going to build next
+                            continue;
+                        } else {
+                            if (oldLength == 1 && newParams[0] == typeof(string)) {
+                                // Special case exceptions to improve interop. Ruby's default message for an exception is the name of the exception class.
+                                ConstructorBuilder cbSpecial = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(RubyClass) });
+                                ILGen ilSpecial = new ILGen(cbSpecial.GetILGenerator());
+                                // : base(RubyOps.GetDefaultExceptionMessage(class))
+                                ilSpecial.EmitLoadArg(0);
+                                ilSpecial.EmitLoadArg(1);
+                                ilSpecial.Emit(OpCodes.Call, Methods.GetDefaultExceptionMessage);
+                                ilSpecial.Emit(OpCodes.Call, baseCtor);
+                                ilSpecial.EmitLoadArg(0);
+                                ilSpecial.EmitLoadArg(1);
+                                ilSpecial.EmitFieldSet(_classField);
+                                ilSpecial.Emit(OpCodes.Ret);
+                            }
+                        }
+                    }
 
-            // TODO: we should redefine all visible constructors from the base class.
+                    // Add RubyClass to the head of the parameter list
+                    newParams.Insert(0, typeof(RubyClass));
+                }
 
-            // Special case exceptions to improve interop. Ruby's default message for an exception is the name of the exception class.
-            if (_tb.IsSubclassOf(typeof(Exception)) && 
-                IsAvailable(baseCtor = _tb.BaseType.GetConstructor(bindingFlags, null, new[] { typeof(string) }, null))) {
-
-                // : base(RubyOps.GetDefaultExceptionMessage(class))
+                // Build a new constructor based on this base class ctor
+                ConstructorBuilder cb = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, newParams.ToArray());
+                ILGen il = new ILGen(cb.GetILGenerator());
                 il.EmitLoadArg(0);
-                il.EmitLoadArg(1);
-                il.Emit(OpCodes.Call, Methods.GetDefaultExceptionMessage);
+                for (int i = startPos; i < oldLength; i++) {
+                    il.EmitLoadArg(i);
+                }
                 il.Emit(OpCodes.Call, baseCtor);
-            } else if (IsAvailable(baseCtor = _tb.BaseType.GetConstructor(bindingFlags, null, new[] { typeof(RubyClass) }, null))) {
-                // : base(class)
-                il.EmitLoadArg(0);
-                il.EmitLoadArg(1);
-                il.Emit(OpCodes.Call, baseCtor);
-            } else if (IsAvailable(baseCtor = _tb.BaseType.GetConstructor(bindingFlags, null, Type.EmptyTypes, null))) {
-                // : base()
-                il.EmitLoadArg(0);
-                il.Emit(OpCodes.Call, baseCtor);
-            } else {
-                throw new NotSupportedException("No compatible constructor found for class " + _tb.BaseType.FullName);
+                if (!isDeserializer) {
+                    // ctor(RubyClass! class, ...) : ... { this._class = class; } 
+                    il.EmitLoadArg(0);
+                    il.EmitLoadArg(1);
+                    il.EmitFieldSet(_classField);
+                } else {
+                    // ctor(SerializationInfo! info, StreamingContext! context) : base {
+                    //   RubyOps.DeserializeObject(out this._instanceData, out this._class, info);
+                    // }
+                    il.EmitLoadArg(0);
+                    il.EmitFieldAddress(_instanceDataField);
+                    il.EmitLoadArg(0);
+                    il.EmitFieldAddress(_classField);
+                    il.EmitLoadArg(1);
+                    il.EmitCall(typeof(RubyOps).GetMethod("DeserializeObject"));
+                }
+                il.Emit(OpCodes.Ret);
             }
-
-            il.EmitLoadArg(0);
-            il.EmitLoadArg(1);
-            il.EmitFieldSet(_classField);
-
-            il.Emit(OpCodes.Ret);
-
 #if !SILVERLIGHT
-            // ctor(SerializationInfo! info, StreamingContext! context) : base/this {
-            //   RubyOps.DeserializeObject(out this._instanceData, out this._class, info);
-            // }
+            if (IsAvailable(emptyCtor) && !deserializerFound) {
+                // We didn't previously find a deserialization constructor.  If we can, build one now.
 
-            ConstructorBuilder deserializer = _tb.DefineConstructor(MethodAttributes.Family, CallingConventions.Standard, _deserializerSignature);
-            il = new ILGen(deserializer.GetILGenerator());
+                // ctor(SerializationInfo! info, StreamingContext! context) : this {
+                //   RubyOps.DeserializeObject(out this._instanceData, out this._class, info);
+                // }
 
-            ConstructorInfo baseDeserializer = _tb.BaseType.GetConstructor(bindingFlags, null, _deserializerSignature, null);
+                ConstructorBuilder deserializer = _tb.DefineConstructor(MethodAttributes.Family, CallingConventions.Standard, _deserializerSignature);
+                ILGen dsil = new ILGen(deserializer.GetILGenerator());
 
-            if (IsAvailable(baseDeserializer)) {
-                //   : base(info, context) { 
-                il.EmitLoadArg(0);
-                il.EmitLoadArg(1);
-                il.EmitLoadArg(2);
-                il.Emit(OpCodes.Call, baseDeserializer);
-            } else {
                 //   : this((RubyClass)context.Context) { 
-                il.EmitLoadArg(0);
-                il.EmitLoadArgAddress(2);
-                il.EmitCall(typeof(StreamingContext).GetProperty("Context").GetGetMethod());
-                il.Emit(OpCodes.Castclass, typeof(RubyClass));
-                il.Emit(OpCodes.Call, ctor);
+                dsil.EmitLoadArg(0);
+                dsil.EmitLoadArgAddress(2);
+                dsil.EmitCall(typeof(StreamingContext).GetProperty("Context").GetGetMethod());
+                dsil.Emit(OpCodes.Castclass, typeof(RubyClass));
+                dsil.Emit(OpCodes.Call, emptyCtor);
+
+                dsil.EmitLoadArg(0);
+                dsil.EmitFieldAddress(_instanceDataField);
+                dsil.EmitLoadArg(0);
+                dsil.EmitFieldAddress(_classField);
+                dsil.EmitLoadArg(1);
+                dsil.EmitCall(typeof(RubyOps).GetMethod("DeserializeObject"));
+                dsil.Emit(OpCodes.Ret);
             }
-
-            il.EmitLoadArg(0);
-            il.EmitFieldAddress(_instanceDataField);
-            il.EmitLoadArg(0);
-            il.EmitFieldAddress(_classField);
-            il.EmitLoadArg(1);
-            il.EmitCall(typeof(RubyOps).GetMethod("DeserializeObject"));
-            il.Emit(OpCodes.Ret);
 #endif
         }
 
===================================================================
