edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C785561
File: RubyTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C785561  (server)    3/16/2009 2:51 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;DMO1
@@ -121,6 +121,7 @@
                 
                 AttributeAccessors1,
                 AttributeAccessors2,
+                AttributeAccessors3,
                 
                 Scenario_RubyDeclarations1,
                 Scenario_RubyDeclarations1A,
@@ -479,6 +480,7 @@
                 ClassDuplication6,
                 Clone1,
                 Dup1,
+                Structs1,
                 MetaModules1,
                 MetaModulesDuplication1,
   
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/HostingTests.cs;C771003
File: HostingTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/HostingTests.cs;C771003  (server)    3/16/2009 3:50 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/HostingTests.cs;DMO1
@@ -28,27 +28,27 @@
         public void RubyHosting_DelegateConversions() {
             var lambda = Engine.Execute(@"lambda { |a| a + 1 }");
             var result = Engine.Operations.Invoke(lambda, 5);
-            Debug.Assert((int)result == 6);
+            Assert((int)result == 6);
 
             var func = Engine.Operations.ConvertTo<Func<int, int>>(lambda);
-            Debug.Assert(func(10) == 11);
+            Assert(func(10) == 11);
 
             var method = Engine.Execute(@"def foo(a,b); a + b; end; method(:foo)");
             var func2 = Engine.Operations.ConvertTo<Func<int, int, int>>(method);
-            Debug.Assert(func2(1, 2) == 3);
+            Assert(func2(1, 2) == 3);
 
             Engine.Runtime.Globals.SetVariable("F1", typeof(Func<int, int>));
             var func3 = (Func<int, int>)Engine.Execute(@"F1.to_class.new { |a| a + 3 }");
-            Debug.Assert(func3(1) == 4);
+            Assert(func3(1) == 4);
 
-            // TODO:
-#if TODO
             var func4 = (Func<int, int>)Engine.Execute(@"F1.to_class.new lambda { |a| a + 4 }");
-            Debug.Assert(func4(1) == 5);
+            Assert(func4(1) == 5);
 
             var func5 = (Func<int, int>)Engine.Execute(@"F1.to_class.new(*[lambda { |a| a + 5 }])");
-            Debug.Assert(func5(1) == 6);
+            Assert(func5(1) == 6);
 
+            AssertExceptionThrown<ArgumentException>(() => Engine.Execute(@"F1.to_class.new(*[])"));
+
             if (_driver.RunPython) {
                 var py = Runtime.GetEngine("python");
 
@@ -60,9 +60,8 @@
 ");
                 Engine.Runtime.Globals.SetVariable("PyAdd", pyAdd);
                 var pyFunc = (Func<string[], string[], string[]>)Engine.Execute(@"F2.to_class.new PyAdd");
-                Debug.Assert(String.Join(";", pyFunc(new[] { "x" }, new[] { "y" })) == "x;y");
+                Assert(String.Join(";", pyFunc(new[] { "x" }, new[] { "y" })) == "x;y");
             }
-#endif
         }
 
         public void RubyHosting1A() {
@@ -166,7 +165,7 @@
                 setup.InterpretedMode = true;
             });
 
-            Debug.Assert(ruby.Setup.InterpretedMode == true);
+            Assert(ruby.Setup.InterpretedMode == true);
         }
 
         public void Scenario_RubyEngine1() {
@@ -296,13 +295,13 @@
 end
 ");
             var obj = Engine.Operations.CreateInstance(cls) as RubyObject;
-            Debug.Assert(obj != null && obj.Class.Name == "C");
+            Assert(obj != null && obj.Class.Name == "C");
 
             obj = Engine.Operations.InvokeMember(cls, "new") as RubyObject;
-            Debug.Assert(obj != null && obj.Class.Name == "C");
+            Assert(obj != null && obj.Class.Name == "C");
 
             var foo = Engine.Operations.GetMember(obj, "foo") as RubyMethod;
-            Debug.Assert(foo != null && foo.Name == "foo" && foo.Target == obj);
+            Assert(foo != null && foo.Name == "foo" && foo.Target == obj);
 
             AssertOutput(() => Engine.Operations.Invoke(foo, 1, 2), "[1, 2]");
             AssertOutput(() => Engine.Operations.InvokeMember(obj, "foo", 1, 2), "[1, 2]");
@@ -393,9 +392,9 @@
 end
 ");
             var obj = Engine.Operations.CreateInstance(cls);
-            Debug.Assert(obj != null);
+            Assert(obj != null);
             var ictd = Engine.Operations.CreateInstance(cls) as ICustomTypeDescriptor;
-            Debug.Assert(ictd != null);
+            Assert(ictd != null);
             Assert(ictd.GetClassName() == "C");
             var props = ictd.GetProperties();
             Assert(props.Count == 2);
@@ -414,9 +413,9 @@
 end
 ");
             var obj = Engine.Operations.CreateInstance(cls);
-            Debug.Assert(obj != null);
+            Assert(obj != null);
             var ictd = Engine.Operations.CreateInstance(cls) as ICustomTypeDescriptor;
-            Debug.Assert(ictd != null);
+            Assert(ictd != null);
             Assert(ictd.GetClassName() == "D");
             var props = ictd.GetProperties();
             Assert(props.Count == 1);
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MethodTests.cs;C761017
File: MethodTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MethodTests.cs;C761017  (server)    3/16/2009 4:00 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MethodTests.cs;DMO1
@@ -433,6 +433,28 @@
 ");
         }
 
+        public void AttributeAccessors3() {
+            AssertOutput(() => CompilerTest(@"
+class C
+  attr_accessor :foo 
+  
+  alias set_foo foo=
+end
+
+c = C.new
+
+c.foo = 1
+c.set_foo(*[2])
+c.set_foo(3,4) rescue p $!
+p c.foo(*[])
+p c.foo(1) rescue p $!
+"), @"
+#<ArgumentError: wrong number of arguments (2 for 1)>
+2
+#<ArgumentError: wrong number of arguments (1 for 0)>
+");
+        }
+
         public void MethodAdded1() {
             AssertOutput(delegate {
                 CompilerTest(@"
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C771003
File: RubyClass.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C771003  (server)    3/16/2009 3:40 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;DMO1
@@ -1023,21 +1023,17 @@
                     ));
                 }
             } else {
-                // TODO:
-                throw new NotSupportedException();
-                //var actualArgs = RubyMethodGroupBase.MakeActualArgs(metaBuilder, args, SelfCallConvention.NoSelf, false, false);
-                //if (actualArgs.Length == 1) {
-                //    var convertBinder = args.RubyContext.CreateConvertBinder(type, true);
-                //    var converted = convertBinder.Bind(actualArgs[0], DynamicMetaObject.EmptyMetaObjects);
+                var actualArgs = RubyMethodGroupBase.NormalizeArguments(metaBuilder, args, SelfCallConvention.NoSelf, false, false);
+                if (actualArgs.Length == 1) {
+                    var convertBinder = args.RubyContext.CreateConvertBinder(type, true);
+                    var converted = convertBinder.Bind(actualArgs[0], DynamicMetaObject.EmptyMetaObjects);
 
-                //    // TODO: Should MakeActualArgs return a struct that provides us an information whether to treat particular argument's restrictions as conditions?
-                //    // Items of a splatted array are stored in locals. Therefore we cannot apply restrictions on them.
-                //    metaBuilder.SetMetaResult(converted, args.SimpleArgumentCount == 0 && args.Signature.HasSplattedArgument);
-                //} else {
-                //    metaBuilder.SetError(Methods.MakeWrongNumberOfArgumentsError.OpCall(
-                //        AstUtils.Constant(args.ExplicitArgumentCount - 1), AstUtils.Constant(0)
-                //    ));
-                //}
+                    // TODO: Should NormalizeArguments return a struct that provides us an information whether to treat particular argument's restrictions as conditions?
+                    // The splatted array is stored in a local. Therefore we cannot apply restrictions on it.
+                    metaBuilder.SetMetaResult(converted, args.SimpleArgumentCount == 0 && args.Signature.HasSplattedArgument);
+                } else {
+                    metaBuilder.SetWrongNumberOfArgumentsError(actualArgs.Length, 0);
+                }
             }
         }
 
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyStruct.cs;C759835
File: RubyStruct.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyStruct.cs;C759835  (server)    3/16/2009 2:45 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyStruct.cs;DMO1
@@ -31,6 +31,7 @@
 using System.Runtime.Serialization;
 using System.Security.Permissions;
 using AstUtils = Microsoft.Scripting.Ast.Utils;
+using IronRuby.Compiler.Ast;
 
 namespace IronRuby.Builtins {
 
@@ -164,29 +165,38 @@
 
         private static RuleGenerator/*!*/ CreateGetter(int index) {
             return delegate(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name) {
-                metaBuilder.Result = Ast.Call(
-                    Ast.Convert(args.TargetExpression, typeof(RubyStruct)),
-                    typeof(RubyStruct).GetMethod("GetValue"),
-                    AstUtils.Constant(index)
-                );
+                
+                var actualArgs = RubyMethodGroupInfo.NormalizeArguments(metaBuilder, args, SelfCallConvention.NoSelf, false, false);
+                if (actualArgs.Length == 0) {
+                    metaBuilder.Result = Ast.Call(
+                        Ast.Convert(args.TargetExpression, typeof(RubyStruct)),
+                        Methods.RubyStruct_GetValue,
+                        AstUtils.Constant(index)
+                    );
+                } else {
+                    metaBuilder.SetWrongNumberOfArgumentsError(actualArgs.Length, 0);
+                }
             };
         }
 
         private static RuleGenerator/*!*/ CreateSetter(int index) {
             return delegate(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name) {
 
-                var actualArgs = RubyMethodGroupInfo.MakeActualArgs(metaBuilder, args, SelfCallConvention.SelfIsParameter, false, false);
-
-                metaBuilder.Result = Ast.Call(
-                    Ast.Convert(actualArgs[0], typeof(RubyStruct)),
-                    typeof(RubyStruct).GetMethod("SetValue"),
-                    AstUtils.Constant(index),
-                    Ast.Convert(actualArgs[1], typeof(object))
-                );
+                var actualArgs = RubyMethodGroupInfo.NormalizeArguments(metaBuilder, args, SelfCallConvention.NoSelf, false, false);
+                if (actualArgs.Length == 1) {
+                    metaBuilder.Result = Ast.Call(
+                        Ast.Convert(args.TargetExpression, typeof(RubyStruct)),
+                        Methods.RubyStruct_SetValue,
+                        AstUtils.Constant(index),
+                        AstFactory.Box(actualArgs[0].Expression)
+                    );
+                } else {
+                    metaBuilder.SetWrongNumberOfArgumentsError(actualArgs.Length, 1);
+                }
             };
         }
 
-        #endregion 
+        #endregion
 
         public int GetIndex(string/*!*/ name) {
             int result;
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/ReflectionCache.cs;C735797
File: ReflectionCache.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/ReflectionCache.cs;C735797  (server)    3/16/2009 3:27 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/ReflectionCache.cs;DMO1
@@ -51,11 +51,13 @@
     internal static partial class Methods {
         private static ConstructorInfo _RubyCallSignatureCtor;
         private static MethodInfo _Stopwatch_GetTimestamp, _IEnumerable_Of_Object_GetEnumerator, _IEnumerator_MoveNext,
-            _IEnumerator_get_Current;
+            _IEnumerator_get_Current, _RubyStruct_GetValue, _RubyStruct_SetValue;
 
         public static ConstructorInfo RubyCallSignatureCtor { get { return _RubyCallSignatureCtor ?? (_RubyCallSignatureCtor = GetConstructor(typeof(RubyCallSignature), typeof(uint))); } }
 
         public static MethodInfo Stopwatch_GetTimestamp { get { return _Stopwatch_GetTimestamp ?? (_Stopwatch_GetTimestamp = GetMethod(typeof(Stopwatch), "GetTimestamp")); } }
+        public static MethodInfo RubyStruct_GetValue { get { return _RubyStruct_GetValue ?? (_RubyStruct_GetValue = GetMethod(typeof(RubyStruct), "GetValue", BindingFlags.Instance, typeof(int))); } }
+        public static MethodInfo RubyStruct_SetValue { get { return _RubyStruct_SetValue ?? (_RubyStruct_SetValue = GetMethod(typeof(RubyStruct), "SetValue", BindingFlags.Instance, typeof(int), typeof(object))); } }
         public static MethodInfo IEnumerable_Of_Object_GetEnumerator { get { return _IEnumerable_Of_Object_GetEnumerator ?? (_IEnumerable_Of_Object_GetEnumerator = GetMethod(typeof(IEnumerable<object>), "GetEnumerator", BindingFlags.Instance, Type.EmptyTypes)); } }
         public static MethodInfo IEnumerator_get_Current { get { return _IEnumerator_get_Current ?? (_IEnumerator_get_Current = GetMethod(typeof(IEnumerator), "get_Current", BindingFlags.Instance, Type.EmptyTypes)); } }
         public static MethodInfo IEnumerator_MoveNext { get { return _IEnumerator_MoveNext ?? (_IEnumerator_MoveNext = GetMethod(typeof(IEnumerator), "MoveNext", BindingFlags.Instance, Type.EmptyTypes)); } }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/BlockParam.cs;C651054
File: BlockParam.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/BlockParam.cs;C651054  (server)    3/16/2009 1:13 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/BlockParam.cs;DMO1
@@ -27,6 +27,7 @@
 using AstFactory = IronRuby.Compiler.Ast.AstFactory;
 using AstUtils = Microsoft.Scripting.Ast.Utils;
 using IronRuby.Compiler.Generation;
+using System.Dynamic;
 
 namespace IronRuby.Runtime {
     
@@ -42,6 +43,13 @@
     }
 
     internal sealed class MissingBlockParam {
+        internal static readonly DynamicMetaObject MetaObject;
+
+        static MissingBlockParam() {
+            var value = new MissingBlockParam();
+            var constant = Ast.Constant(value);
+            MetaObject = new DynamicMetaObject(constant, BindingRestrictions.GetTypeRestriction(constant, typeof(MissingBlockParam)), value);
+        }
     }
 
     public sealed partial class BlockParam {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/MetaObjectBuilder.cs;C771003
File: MetaObjectBuilder.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/MetaObjectBuilder.cs;C771003  (server)    3/16/2009 3:47 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/MetaObjectBuilder.cs;DMO1
@@ -99,20 +99,28 @@
             SetError(Methods.MakeWrongNumberOfArgumentsError.OpCall(AstUtils.Constant(actual), AstUtils.Constant(expected)));
         }
 
+        public void SetMetaResult(DynamicMetaObject/*!*/ metaResult, bool treatRestrictionsAsConditions) {
+            _result = metaResult.Expression;
+            AddRestriction(metaResult.Restrictions.ToExpression(), treatRestrictionsAsConditions);
+        }
+
         public void AddCondition(Expression/*!*/ condition) {
             Assert.NotNull(condition);
             _condition = (_condition != null) ? Ast.AndAlso(_condition, condition) : condition;
         }
 
         public void AddRestriction(Expression/*!*/ restriction) {
+            AddRestriction(restriction, false);
+        }
+
+        public void AddRestriction(Expression/*!*/ restriction, bool treatRestrictionsAsConditions) {
             Assert.NotNull(restriction);
-            if (_treatRestrictionsAsConditions) {
+            if (treatRestrictionsAsConditions || _treatRestrictionsAsConditions) {
                 AddCondition(restriction);
             } else {
                 _restriction = (_restriction != null) ? Ast.AndAlso(_restriction, restriction) : restriction;
             }
         }
-
         public static Expression/*!*/ GetObjectTypeTestExpression(object value, Expression/*!*/ expression) {
             if (value == null) {
                 return Ast.Equal(expression, AstUtils.Constant(null));
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyAccessorInfo.cs;C735797
File: RubyAccessorInfo.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyAccessorInfo.cs;C735797  (server)    3/16/2009 4:01 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyAccessorInfo.cs;DMO1
@@ -51,11 +51,16 @@
         }
 
         internal override void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name) {
-            metaBuilder.Result = Methods.GetInstanceVariable.OpCall(
-                args.ScopeExpression,
-                AstFactory.Box(args.TargetExpression),
-                AstUtils.Constant(InstanceVariableName)
-            );
+            var actualArgs = RubyMethodGroupInfo.NormalizeArguments(metaBuilder, args, SelfCallConvention.NoSelf, false, false);
+            if (actualArgs.Length == 0) {
+                metaBuilder.Result = Methods.GetInstanceVariable.OpCall(
+                    args.ScopeExpression,
+                    AstFactory.Box(args.TargetExpression),
+                    AstUtils.Constant(InstanceVariableName)
+                );
+            } else {
+                metaBuilder.SetWrongNumberOfArgumentsError(actualArgs.Length, 0);
+            }
         }
 
         protected internal override RubyMemberInfo/*!*/ Copy(RubyMemberFlags flags, RubyModule/*!*/ module) {
@@ -73,15 +78,17 @@
         }
 
         internal override void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name) {
-
-            var actualArgs = RubyMethodGroupInfo.MakeActualArgs(metaBuilder, args, SelfCallConvention.SelfIsParameter, false, false);
-
-            metaBuilder.Result = Methods.SetInstanceVariable.OpCall(
-                AstFactory.Box(actualArgs[0]),
-                AstFactory.Box(actualArgs[1]),
-                args.ScopeExpression,
-                AstUtils.Constant(InstanceVariableName)
-            );
+            var actualArgs = RubyMethodGroupInfo.NormalizeArguments(metaBuilder, args, SelfCallConvention.NoSelf, false, false);
+            if (actualArgs.Length == 1) {
+                metaBuilder.Result = Methods.SetInstanceVariable.OpCall(
+                    AstFactory.Box(args.TargetExpression),
+                    AstFactory.Box(actualArgs[0].Expression),
+                    args.ScopeExpression,
+                    AstUtils.Constant(InstanceVariableName)
+                );
+            } else {
+                metaBuilder.SetWrongNumberOfArgumentsError(actualArgs.Length, 1);
+            }
         }
 
         protected internal override RubyMemberInfo/*!*/ Copy(RubyMemberFlags flags, RubyModule/*!*/ module) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyBinder.cs;C771003
File: RubyBinder.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyBinder.cs;C771003  (server)    3/16/2009 1:23 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyBinder.cs;DMO1
@@ -47,6 +47,13 @@
             _context = context;
         }
 
+        internal static readonly DynamicMetaObject NullMetaObject =
+            new DynamicMetaObject(
+                AstUtils.Constant(null, typeof(DynamicNull)),
+                BindingRestrictions.GetTypeRestriction(AstUtils.Constant(null, typeof(DynamicNull)), typeof(DynamicNull)),
+                null
+            );
+
         protected override string GetTypeName(Type t) {
             RubyModule module;
             return _context.TryGetModule(t, out module) ? module.Name : RubyUtils.GetQualifiedName(t);
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMethodGroupBase.cs;C759835
File: RubyMethodGroupBase.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMethodGroupBase.cs;C759835  (server)    3/16/2009 2:56 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMethodGroupBase.cs;DMO1
@@ -226,13 +226,23 @@
 
             // Allocates a variable holding BlockParam. At runtime the BlockParam is created with a new RFC instance that
             // identifies the library method frame as a proc-converter target of a method unwinder triggered by break from a block.
-            //
-            // NOTE: We check for null block here -> test for that fact is added in MakeActualArgs
-            if (args.Signature.HasBlock && args.GetBlock() != null && calleeHasBlockParam) {
-                if (metaBuilder.BfcVariable == null) {
-                    metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
+            if (args.Signature.HasBlock) {
+                var metaBlock = args.GetMetaBlock();
+                if (metaBlock.Value != null && calleeHasBlockParam) {
+                    if (metaBuilder.BfcVariable == null) {
+                        metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
+                    }
+                    metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder;
                 }
-                metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder;
+
+                // Block test - we need to test for a block regardless of whether it is actually passed to the method or not
+                // since the information that the block is not null is used for overload resolution.
+                if (metaBlock.Value == null) {
+                    metaBuilder.AddRestriction(Ast.Equal(metaBlock.Expression, AstUtils.Constant(null)));
+                } else {
+                    // don't need to test the exact type of the Proc since the code is subclass agnostic:
+                    metaBuilder.AddRestriction(Ast.NotEqual(metaBlock.Expression, AstUtils.Constant(null)));
+                }
             }
 
             var actualArgs = MakeActualArgs(metaBuilder, args, callConvention, calleeHasBlockParam, true);
@@ -302,39 +312,98 @@
             return false;
         }
 
-        internal static Expression[]/*!*/ MakeActualArgs(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args,
+        // Normalizes arguments: inserts self, expands splats, and inserts rhs arg. 
+        // Adds any restrictions/conditions applied to the arguments to the given meta-builder.
+        internal static DynamicMetaObject[]/*!*/ NormalizeArguments(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args,
             SelfCallConvention callConvention, bool calleeHasBlockParam, bool injectMissingBlockParam) {
 
-            var actualArgs = new List<Expression>(args.ExplicitArgumentCount);
+            var result = new List<DynamicMetaObject>();
 
             // self (instance):
             if (callConvention == SelfCallConvention.SelfIsInstance) {
+                result.Add(args.MetaTarget);
+            }
+
+            // block:
+            if (calleeHasBlockParam) {
+                if (args.Signature.HasBlock) {
+                    if (args.GetMetaBlock() == null) {
+                        // the user explicitly passed nil as a block arg:
+                        result.Add(RubyBinder.NullMetaObject);
+                    } else {
+                        // pass BlockParam:
+                        Debug.Assert(metaBuilder.BfcVariable != null);
+                        result.Add(new DynamicMetaObject(metaBuilder.BfcVariable, BindingRestrictions.Empty));
+                    }
+                } else {
+                    // no block passed into a method with a BlockParam:
+                    result.Add(RubyBinder.NullMetaObject);
+                }
+            } else if (injectMissingBlockParam) {
+                // no block passed into a method w/o a BlockParam (we still need to fill the missing block argument):
+                result.Add(RubyBinder.NullMetaObject);
+            }
+
+            // self (parameter):
+            if (callConvention == SelfCallConvention.SelfIsParameter) {
+                result.Add(args.MetaTarget);
+            }
+
+            // simple arguments:
+            for (int i = 0; i < args.SimpleArgumentCount; i++) {
+                result.Add(args.GetSimpleMetaArgument(i));
+            }
+
+            // splat argument:
+            int listLength;
+            ParameterExpression listVariable;
+            if (args.Signature.HasSplattedArgument) {
+                var splatted = args.GetSplattedMetaArgument();
+
+                if (metaBuilder.AddSplattedArgumentTest(splatted.Value, splatted.Expression, out listLength, out listVariable)) {
+
+                    // AddTestForListArg only returns 'true' if the argument is a List<object>
+                    var list = (List<object>)splatted.Value;
+
+                    // get arguments, add tests
+                    for (int j = 0; j < listLength; j++) {
+                        result.Add(DynamicMetaObject.Create(
+                            list[j], 
+                            Ast.Call(listVariable, typeof(List<object>).GetMethod("get_Item"), AstUtils.Constant(j))
+                        ));
+                    }
+
+                } else {
+                    // argument is not an array => add the argument itself:
+                    result.Add(splatted);
+                }
+            }
+
+            // rhs argument:
+            if (args.Signature.HasRhsArgument) {
+                result.Add(args.GetRhsMetaArgument());
+            }
+
+            return result.ToArray();
+        }
+
+        // TODO: OBSOLETE
+        private static Expression[]/*!*/ MakeActualArgs(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args,
+            SelfCallConvention callConvention, bool calleeHasBlockParam, bool injectMissingBlockParam) {
+
+            var actualArgs = new List<Expression>();
+
+            // self (instance):
+            if (callConvention == SelfCallConvention.SelfIsInstance) {
                 // test already added by method resolver
                 Debug.Assert(args.TargetExpression != null);
                 AddArgument(actualArgs, args.Target, args.TargetExpression);
             }
 
-            Proc block = null;
-            Expression blockExpression = null;
-
-            // block test - we need to test for a block regardless of whether it is actually passed to the method or not
-            // since the information that the block is not null is used for overload resolution.
-            if (args.Signature.HasBlock) {
-                block = args.GetBlock();
-                blockExpression = args.GetBlockExpression();
-
-                if (block == null) {
-                    metaBuilder.AddRestriction(Ast.Equal(blockExpression, AstUtils.Constant(null)));
-                } else {
-                    // don't need to test the exact type of the Proc since the code is subclass agnostic:
-                    metaBuilder.AddRestriction(Ast.NotEqual(blockExpression, AstUtils.Constant(null)));
-                }
-            }
-
             // block:
             if (calleeHasBlockParam) {
                 if (args.Signature.HasBlock) {
-                    if (block == null) {
+                    if (args.GetBlock() == null) {
                         // the user explicitly passed nil as a block arg:
                         actualArgs.Add(AstUtils.Constant(null));
                     } else {
@@ -362,6 +431,7 @@
                 var value = args.GetSimpleArgument(i);
                 var expr = args.GetSimpleArgumentExpression(i);
 
+                // TODO: overload-resolution restrictions
                 metaBuilder.AddObjectTypeRestriction(value, expr);
                 AddArgument(actualArgs, value, expr);
             }
@@ -383,6 +453,7 @@
                         var value = list[j];
                         var expr = Ast.Call(listVariable, typeof(List<object>).GetMethod("get_Item"), AstUtils.Constant(j));
 
+                        // TODO: overload-resolution restrictions
                         metaBuilder.AddObjectTypeCondition(value, expr);
                         AddArgument(actualArgs, value, expr);
                     }
@@ -398,6 +469,7 @@
                 var value = args.GetRhsArgument();
                 var expr = args.GetRhsArgumentExpression();
 
+                // TODO: overload-resolution restrictions
                 metaBuilder.AddObjectTypeRestriction(value, expr);
                 AddArgument(actualArgs, value, expr);
             }
@@ -405,6 +477,7 @@
             return actualArgs.ToArray();
         }
 
+        // TODO: OBSOLETE
         private static void AddArgument(List<Expression>/*!*/ actualArgs, object arg, Expression/*!*/ expr) {
             if (arg == null) {
                 actualArgs.Add(AstUtils.Constant(null));
@@ -418,6 +491,7 @@
             }
         }
 
+        // TODO: OBSOLETE
         private static Type[]/*!*/ GetSignatureToMatch(CallArguments/*!*/ args, SelfCallConvention callConvention) {
             var result = new List<Type>(args.ExplicitArgumentCount);
 
===================================================================
