public void OverloadResolution_Block()
        {
            var t = GetType();

            var gse   = new GlobalScopeExtension(Context, new Scope(), new object(), true);
            var scope = new RubyTopLevelScope(gse, null, new SymbolDictionary());
            var proc  = new Proc(ProcKind.Proc, null, scope, new BlockDispatcher0((x, y) => null, BlockSignatureAttributes.None));

            var scopeArg    = new MetaObject(Ast.Constant(proc.LocalScope), Restrictions.Empty, proc.LocalScope);
            var contextArg  = new MetaObject(Ast.Constant(Context), Restrictions.Empty, Context);
            var instanceInt = new MetaObject(Ast.Constant(1), Restrictions.Empty, 1);
            var str         = "foo";
            var instanceStr = new MetaObject(Ast.Constant(str), Restrictions.Empty, str);
            var procArg     = new MetaObject(Ast.Constant(proc), Restrictions.Empty, proc);
            var nullArg     = new MetaObject(Ast.Constant(Ast.Constant(null)), Restrictions.Empty, null);

            var arguments = new[] {
                // 1.times
                new CallArguments(scopeArg, instanceInt, new MetaObject[0], RubyCallSignature.WithScope(0)),
                // 1.times &nil
                new CallArguments(scopeArg, instanceInt, new[] { nullArg }, RubyCallSignature.WithScopeAndBlock(0)),
                // 1.times &p
                new CallArguments(contextArg, instanceInt, new[] { procArg }, RubyCallSignature.WithBlock(0)),
                // obj.times &p
                new CallArguments(contextArg, instanceStr, new[] { procArg }, RubyCallSignature.WithBlock(0)),
            };

            var results = new[] {
                "Times2",
                "Times1",
                "Times3",
                "Times4",
            };

            for (int i = 0; i < arguments.Length; i++)
            {
                var bindingTarget = RubyMethodGroupInfo.ResolveOverload("times", new[] {
                    t.GetMethod("Times1"),
                    t.GetMethod("Times2"),
                    t.GetMethod("Times3"),
                    t.GetMethod("Times4"),
                }, arguments[i], true, false);

                Assert(bindingTarget.Success);
                Assert(bindingTarget.Method.Name == results[i]);
            }
        }
        public void OverloadResolution_Block1()
        {
            var scope = Context.EmptyScope;
            var proc  = new Proc(ProcKind.Proc, null, scope, new BlockDispatcher0(BlockSignatureAttributes.None, null, 0).
                                 SetMethod(new BlockCallTarget0((x, y) => null)));

            var arguments = new[] {
                // 1.times
                new CallArguments(Context, MO(scope), new[] { MO(1) }, RubyCallSignature.WithScope(0)),
                // 1.times &nil
                new CallArguments(Context, MO(scope), new[] { MO(1), MO(null) }, RubyCallSignature.WithScopeAndBlock(0)),
                // 1.times &p
                new CallArguments(Context, MO(1), new[] { MO(proc) }, RubyCallSignature.WithBlock(0)),
                // obj.times &p
                new CallArguments(Context, MO("foo"), new[] { MO(proc) }, RubyCallSignature.WithBlock(0)),
            };

            var results = new[] {
                "Times2",
                "Times1",
                "Times3",
                "Times4",
            };

            var metaBuilder = new MetaObjectBuilder(null);

            for (int i = 0; i < arguments.Length; i++)
            {
                RubyOverloadResolver resolver;

                var methods = GetStaticMethodsStartingWith(typeof(OverloadsWithBlock), "Times");

                var bindingTarget = RubyMethodGroupInfo.ResolveOverload(
                    metaBuilder, arguments[i], "times", methods, SelfCallConvention.SelfIsParameter,
                    false, out resolver
                    );

                Assert(bindingTarget.Success);
                Assert(bindingTarget.Overload.Name == results[i]);
            }
        }