2009-06-29 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / ecore.cs
index eb51da851ffdb1b159744bf92602ed2e976ff0a8..cc6d1bdd23712d23aff6f9952fc7fea66767edfb 100644 (file)
@@ -298,7 +298,7 @@ namespace Mono.CSharp {
 
                        return te;
                }
-
+       
                public TypeExpr ResolveAsBaseTerminal (IResolveContext ec, bool silent)
                {
                        int errors = Report.Errors;
@@ -363,6 +363,11 @@ namespace Mono.CSharp {
                }
 
                public virtual void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
+               {
+                       Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
+               }
+
+               protected void Error_ValueCannotBeConvertedCore (EmitContext ec, Location loc, Type target, bool expl)
                {
                        // The error was already reported as CS1660
                        if (type == TypeManager.anonymous_method_type)
@@ -547,7 +552,7 @@ namespace Mono.CSharp {
                ///   Currently ResolveLValue wraps DoResolveLValue to perform sanity
                ///   checking and assertion checking on what we expect from Resolve
                /// </remarks>
-               public Expression ResolveLValue (EmitContext ec, Expression right_side, Location loc)
+               public Expression ResolveLValue (EmitContext ec, Expression right_side)
                {
                        int errors = Report.Errors;
                        bool out_access = right_side == EmptyExpression.OutAccess;
@@ -937,8 +942,8 @@ namespace Mono.CSharp {
                        if (operator_group == null)
                                return null;
 
-                       ArrayList arguments = new ArrayList (1);
-                       arguments.Add (new Argument (e, Argument.AType.Expression));
+                       Arguments arguments = new Arguments (1);
+                       arguments.Add (new Argument (e));
                        operator_group = operator_group.OverloadResolve (
                                ec, ref arguments, false, loc);
 
@@ -1100,7 +1105,7 @@ namespace Mono.CSharp {
                                        ig.Emit (OpCodes.Ldind_Ref);
                                else
                                        LoadFromPtr (ig, TypeManager.GetEnumUnderlyingType (t));
-                       } else if (t.IsValueType || TypeManager.IsGenericParameter (t))
+                       } else if (TypeManager.IsStruct (t) || TypeManager.IsGenericParameter (t))
                                ig.Emit (OpCodes.Ldobj, t);
                        else if (t.IsPointer)
                                ig.Emit (OpCodes.Ldind_I);
@@ -1131,7 +1136,7 @@ namespace Mono.CSharp {
                                ig.Emit (OpCodes.Stind_I1);
                        else if (type == TypeManager.intptr_type)
                                ig.Emit (OpCodes.Stind_I);
-                       else if (type.IsValueType || TypeManager.IsGenericParameter (type))
+                       else if (TypeManager.IsStruct (type) || TypeManager.IsGenericParameter (type))
                                ig.Emit (OpCodes.Stobj, type);
                        else
                                ig.Emit (OpCodes.Stind_Ref);
@@ -1262,17 +1267,17 @@ namespace Mono.CSharp {
                //
                public abstract Expression CreateExpressionTree (EmitContext ec);
 
-               protected Expression CreateExpressionFactoryCall (string name, ArrayList args)
+               protected Expression CreateExpressionFactoryCall (string name, Arguments args)
                {
                        return CreateExpressionFactoryCall (name, null, args, loc);
                }
 
-               protected Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args)
+               protected Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args)
                {
                        return CreateExpressionFactoryCall (name, typeArguments, args, loc);
                }
 
-               public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args, Location loc)
+               public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args, Location loc)
                {
                        return new Invocation (new MemberAccess (CreateExpressionTypeExpression (loc), name, typeArguments, loc), args);
                }
@@ -1359,7 +1364,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       Arguments args = new Arguments (2);
                        args.Add (new Argument (child.CreateExpressionTree (ec)));
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
 
@@ -1580,9 +1585,10 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
-                       args.Add (new Argument (child.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+                       Arguments args = Arguments.CreateForExpressionTree (ec, null,
+                               child.CreateExpressionTree (ec),
+                               new TypeOf (new TypeExpression (type, loc), loc));
+
                        if (type.IsPointer)
                                Error_PointerInsideExpressionTree ();
 
@@ -1612,12 +1618,18 @@ namespace Mono.CSharp {
                
                public override void Emit (EmitContext ec)
                {
-                       child.Emit (ec);
+                       child.Emit (ec);                        
                }
 
                public override void EmitBranchable (EmitContext ec, Label label, bool on_true)
                {
                        child.EmitBranchable (ec, label, on_true);
+
+#if GMCS_SOURCE
+                       // Only to make verifier happy
+                       if (TypeManager.IsGenericParameter (type) && child.IsNull)
+                               ec.ig.Emit (OpCodes.Unbox_Any, type);
+#endif
                }
 
                public override void EmitSideEffect (EmitContext ec)
@@ -1708,7 +1720,7 @@ namespace Mono.CSharp {
                        //
                        // This works only sometimes
                        //
-                       if (type.Module == CodeGen.Module.Builder)
+                       if (type.Module == RootContext.ToplevelTypes.Builder)
                                return Child.GetValue ();
 #endif
 
@@ -1807,7 +1819,7 @@ namespace Mono.CSharp {
                {
                        // boxing is side-effectful, since it involves runtime checks, except when boxing to Object or ValueType
                        // so, we need to emit the box+pop instructions in most cases
-                       if (child.Type.IsValueType &&
+                       if (TypeManager.IsStruct (child.Type) &&
                            (type == TypeManager.object_type || type == TypeManager.value_type))
                                child.EmitSideEffect (ec);
                        else
@@ -1838,19 +1850,16 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       
                        base.Emit (ec);
-#if GMCS_SOURCE
-                       if (type.IsGenericParameter || type.IsGenericType && type.IsValueType)
-                               ig.Emit (OpCodes.Unbox_Any, type);
-                       else
-#endif
-                       {
-                               ig.Emit (OpCodes.Unbox, type);
 
-                               LoadFromPtr (ig, type);
-                       }
+                       ILGenerator ig = ec.ig;
+
+#if GMCS_SOURCE
+                       ig.Emit (OpCodes.Unbox_Any, type);
+#else                  
+                       ig.Emit (OpCodes.Unbox, type);
+                       LoadFromPtr (ig, type);
+#endif                 
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
@@ -2108,46 +2117,38 @@ namespace Mono.CSharp {
        ///   to the class requested
        /// </summary>
        public sealed class ClassCast : TypeCast {
-               Type child_generic_parameter;
-
+               readonly bool forced;
+               
                public ClassCast (Expression child, Type return_type)
                        : base (child, return_type)
-                       
                {
-                       if (TypeManager.IsGenericParameter (child.Type))
-                               child_generic_parameter = child.Type;
                }
-
-               public override Expression DoResolve (EmitContext ec)
+               
+               public ClassCast (Expression child, Type return_type, bool forced)
+                       : base (child, return_type)
                {
-                       // This should never be invoked, we are born in fully
-                       // initialized state.
-
-                       return this;
+                       this.forced = forced;
                }
 
                public override void Emit (EmitContext ec)
                {
                        base.Emit (ec);
 
-                       if (child_generic_parameter != null)
-                               ec.ig.Emit (OpCodes.Box, child_generic_parameter);
-
 #if GMCS_SOURCE
-                       if (type.IsGenericParameter)
+                       bool gen = TypeManager.IsGenericParameter (child.Type);
+                       if (gen)
+                               ec.ig.Emit (OpCodes.Box, child.Type);
+                       
+                       if (type.IsGenericParameter) {
                                ec.ig.Emit (OpCodes.Unbox_Any, type);
-                       else
+                               return;
+                       }
+                       
+                       if (gen && !forced)
+                               return;
 #endif
-                               ec.ig.Emit (OpCodes.Castclass, type);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-                       if (child_generic_parameter != null)
-                               child_generic_parameter = storey.MutateGenericArgument (child_generic_parameter);
-
-                       base.MutateHoistedGenericType (storey);
+                       
+                       ec.ig.Emit (OpCodes.Castclass, type);
                }
        }
 
@@ -2327,6 +2328,18 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override bool Equals (object obj)
+               {
+                       ATypeNameExpression atne = obj as ATypeNameExpression;
+                       return atne != null && atne.Name == Name &&
+                               (targs == null || targs.Equals (atne.targs));
+               }
+
+               public override int GetHashCode ()
+               {
+                       return Name.GetHashCode ();
+               }
+
                public override string GetSignatureForError ()
                {
                        if (targs != null) {
@@ -2358,7 +2371,7 @@ namespace Mono.CSharp {
                public SimpleName (string name, TypeParameter[] type_params, Location l)
                        : base (name, l)
                {
-                       targs = new TypeArguments (l);
+                       targs = new TypeArguments ();
                        foreach (TypeParameter type_param in type_params)
                                targs.Add (new TypeParameterExpr (type_param, l));
                }
@@ -2461,7 +2474,7 @@ namespace Mono.CSharp {
 
                        for (; (ds != null) && ds.IsGeneric; ds = ds.Parent) {
                                if (arg_count + ds.CountTypeParameters == gen_params.Length) {
-                                       TypeArguments new_args = new TypeArguments (loc);
+                                       TypeArguments new_args = new TypeArguments ();
                                        foreach (TypeParameter param in ds.TypeParameters)
                                                new_args.Add (new TypeParameterExpr (param, loc));
 
@@ -2517,7 +2530,7 @@ namespace Mono.CSharp {
 
                        string ns = ec.DeclContainer.NamespaceEntry.NS.Name;
                        string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
-                       foreach (Assembly a in RootNamespace.Global.Assemblies) {
+                       foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
                                Type type = a.GetType (fullname);
                                if (type != null) {
                                        Report.SymbolRelatedToPreviousError (type);
@@ -2611,7 +2624,7 @@ namespace Mono.CSharp {
                                if (vi != null){
                                        LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
                                        if (right_side != null) {
-                                               return var.ResolveLValue (ec, right_side, loc);
+                                               return var.ResolveLValue (ec, right_side);
                                        } else {
                                                ResolveFlags rf = ResolveFlags.VariableOrValue;
                                                if (intermediate)
@@ -2621,12 +2634,9 @@ namespace Mono.CSharp {
                                }
 
                                Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
-                               if (expr == null)
-                                       expr = current_block.Toplevel.GetTransparentIdentifier (Name);
-
                                if (expr != null) {
                                        if (right_side != null)
-                                               return expr.ResolveLValue (ec, right_side, loc);
+                                               return expr.ResolveLValue (ec, right_side);
 
                                        return expr.Resolve (ec);
                                }
@@ -2656,6 +2666,9 @@ namespace Mono.CSharp {
                                        } else if (e is EventExpr) {
                                                if (((EventExpr) e).IsAccessibleFrom (ec.ContainerType))
                                                        break;
+                                       } else if (targs != null && e is TypeExpression) {
+                                               e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
+                                               break;
                                        } else {
                                                break;
                                        }
@@ -2700,18 +2713,8 @@ namespace Mono.CSharp {
                                        almost_matched_members = almost_matched;
                                if (almost_matched_type == null)
                                        almost_matched_type = ec.ContainerType;
-                               Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
+                               return Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
                                        ec.DeclContainer.Name, AllMemberTypes, AllBindingFlags);
-                               return null;
-                       }
-
-                       if (e is TypeExpr) {
-                               if (targs == null)
-                                       return e;
-
-                               GenericTypeExpr ct = new GenericTypeExpr (
-                                       e.Type, targs, loc);
-                               return ct.ResolveAsTypeStep (ec, false);
                        }
 
                        if (e is MemberExpr) {
@@ -2749,11 +2752,13 @@ namespace Mono.CSharp {
                                        return null;
 
                                if (targs != null) {
-                                       targs.Resolve (ec);
+                                       if (!targs.Resolve (ec))
+                                               return null;
+
                                        me.SetTypeArguments (targs);
                                }
 
-                               if (!me.IsStatic && (me.InstanceExpression != null) &&
+                               if (!me.IsStatic && (me.InstanceExpression != null && me.InstanceExpression != EmptyExpression.Null) &&
                                    TypeManager.IsNestedFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
                                    me.InstanceExpression.Type != me.DeclaringType &&
                                    !TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
@@ -2830,17 +2835,12 @@ namespace Mono.CSharp {
                        return ds.CheckAccessLevel (Type);
                }
 
-               public virtual bool AsAccessible (DeclSpace ds)
-               {
-                       return ds.IsAccessibleAs (Type);
-               }
-
                public virtual bool IsClass {
                        get { return Type.IsClass; }
                }
 
                public virtual bool IsValueType {
-                       get { return Type.IsValueType; }
+                       get { return TypeManager.IsStruct (Type); }
                }
 
                public virtual bool IsInterface {
@@ -2907,141 +2907,51 @@ namespace Mono.CSharp {
                }
        }
 
-       /// <summary>
-       ///   Used to create types from a fully qualified name.  These are just used
-       ///   by the parser to setup the core types.  A TypeLookupExpression is always
-       ///   classified as a type.
-       /// </summary>
+       //
+       // Used to create types from a fully qualified name.  These are just used
+       // by the parser to setup the core types.
+       //
        public sealed class TypeLookupExpression : TypeExpr {
+               readonly string ns_name;
                readonly string name;
                
-               public TypeLookupExpression (string name)
+               public TypeLookupExpression (string ns, string name)
                {
                        this.name = name;
+                       this.ns_name = ns;
                        eclass = ExprClass.Type;
                }
 
                public override TypeExpr ResolveAsTypeTerminal (IResolveContext ec, bool silent)
                {
-                       // It's null for corlib compilation only
-                       if (type == null)
-                               return DoResolveAsTypeStep (ec);
+                       //
+                       // It's null only during mscorlib bootstrap when DefineType
+                       // nees to resolve base type of same type
+                       //
+                       // For instance struct Char : IComparable<char>
+                       //
+                       // TODO: it could be removed when Resolve starts to use 
+                       // DeclSpace instead of Type
+                       //
+                       if (type == null) {
+                               Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, false);
+                               FullNamedExpression fne = ns.Lookup (null, name, loc);
+                               if (fne != null)
+                                       type = fne.Type;
+                       }
 
                        return this;
                }
 
-               private class UnexpectedType
-               {
-               }
-
-               // This performes recursive type lookup, providing support for generic types.
-               // For example, given the type:
-               //
-               // System.Collections.Generic.KeyValuePair`2[[System.Int32],[System.String]]
-               //
-               // The types will be checked in the following order:
-               //                                                                             _
-               // System                                                                       |
-               // System.Collections                                                           |
-               // System.Collections.Generic                                                   |
-               //                        _                                                     |
-               //     System              | recursive call 1                                   |
-               //     System.Int32       _|                                                    | main method call
-               //                        _                                                     |
-               //     System              | recursive call 2                                   |
-               //     System.String      _|                                                    |
-               //                                                                              |
-               // System.Collections.Generic.KeyValuePair`2[[System.Int32],[System.String]]   _|
-               //
-               private Type TypeLookup (IResolveContext ec, string name)
-               {
-                       int index = 0;
-                       int dot = 0;
-                       bool done = false;
-                       FullNamedExpression resolved = null;
-                       Type type = null;
-                       Type recursive_type = null;
-                       while (index < name.Length) {
-                               if (name[index] == '[') {
-                                       int open = index;
-                                       int braces = 1;
-                                       do {
-                                               index++;
-                                               if (name[index] == '[')
-                                                       braces++;
-                                               else if (name[index] == ']')
-                                                       braces--;
-                                       } while (braces > 0);
-                                       recursive_type = TypeLookup (ec, name.Substring (open + 1, index - open - 1));
-                                       if (recursive_type == null || (recursive_type == typeof(UnexpectedType)))
-                                               return recursive_type;
-                               }
-                               else {
-                                       if (name[index] == ',')
-                                               done = true;
-                                       else if ((name[index] == '.' && !done) || (index == name.Length && name[0] != '[')) {
-                                               string substring = name.Substring(dot, index - dot);
-
-                                               if (resolved == null)
-                                                       resolved = RootNamespace.Global.Lookup (ec.DeclContainer, substring, Location.Null);
-                                               else if (resolved is Namespace)
-                                                   resolved = (resolved as Namespace).Lookup (ec.DeclContainer, substring, Location.Null);
-                                               else if (type != null)
-                                                       type = TypeManager.GetNestedType (type, substring);
-                                               else
-                                                       return null;
-
-                                               if (resolved == null)
-                                                       return null;
-                                               else if (type == null && resolved is TypeExpr)
-                                                       type = resolved.Type;
-
-                                               dot = index + 1;
-                                       }
-                               }
-                               index++;
-                       }
-                       if (name[0] != '[') {
-                               string substring = name.Substring(dot, index - dot);
-
-                               if (type != null)
-                                       return TypeManager.GetNestedType (type, substring);
-                               
-                               if (resolved != null) {
-                                       resolved = (resolved as Namespace).Lookup (ec.DeclContainer, substring, Location.Null);
-                                       if (resolved is TypeExpr)
-                                               return resolved.Type;
-                                       
-                                       if (resolved == null)
-                                               return null;
-                                       
-                                       resolved.Error_UnexpectedKind (ec.DeclContainer, "type", loc);
-                                       return typeof (UnexpectedType);
-                               }
-                               else
-                                       return null;
-                       }
-                       else
-                               return recursive_type;
-                       }
-
                protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
                {
-                       Type t = TypeLookup (ec, name);
-                       if (t == null) {
-                               NamespaceEntry.Error_NamespaceNotFound (loc, name);
-                               return null;
-                       }
-                       if (t == typeof(UnexpectedType))
-                               return null;
-                       type = t;
                        return this;
                }
 
                public override string GetSignatureForError ()
                {
                        if (type == null)
-                               return TypeManager.CSharpName (name, null);
+                               return TypeManager.CSharpName (ns_name + "." + name, null);
 
                        return base.GetSignatureForError ();
                }
@@ -3176,7 +3086,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (InstanceExpression.Type.IsValueType) {
+                       if (TypeManager.IsValueType (InstanceExpression.Type)) {
                                if (InstanceExpression is IMemoryLocation) {
                                        ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.LoadStore);
                                } else {
@@ -3223,45 +3133,30 @@ namespace Mono.CSharp {
                        get { return namespace_entry == null; }
                }
 
-               public override void EmitArguments (EmitContext ec, ArrayList arguments)
-               {
-                       if (arguments == null)
-                               arguments = new ArrayList (1);                  
-                       arguments.Insert (0, extension_argument);
-                       base.EmitArguments (ec, arguments);
-               }
-
-               public override void EmitCall (EmitContext ec, ArrayList arguments)
-               {
-                       if (arguments == null)
-                               arguments = new ArrayList (1);
-                       arguments.Insert (0, extension_argument);
-                       base.EmitCall (ec, arguments);
-               }
-
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        extension_argument.Expr.MutateHoistedGenericType (storey);
                        base.MutateHoistedGenericType (storey);
                }
 
-               public override MethodGroupExpr OverloadResolve (EmitContext ec, ref ArrayList arguments, bool may_fail, Location loc)
+               public override MethodGroupExpr OverloadResolve (EmitContext ec, ref Arguments arguments, bool may_fail, Location loc)
                {
                        if (arguments == null)
-                               arguments = new ArrayList (1);
+                               arguments = new Arguments (1);
 
                        arguments.Insert (0, new Argument (ExtensionExpression));
-                       MethodGroupExpr mg = ResolveOverloadExtensions (ec, arguments, namespace_entry, loc);
+                       MethodGroupExpr mg = ResolveOverloadExtensions (ec, ref arguments, namespace_entry, loc);
 
                        // Store resolved argument and restore original arguments
                        if (mg != null)
-                               ((ExtensionMethodGroupExpr)mg).extension_argument = (Argument)arguments [0];
-                       arguments.RemoveAt (0);
+                               ((ExtensionMethodGroupExpr)mg).extension_argument = arguments [0];
+                       else
+                               arguments.RemoveAt (0); // Clean-up modified arguments for error reporting
 
                        return mg;
                }
 
-               MethodGroupExpr ResolveOverloadExtensions (EmitContext ec, ArrayList arguments, NamespaceEntry ns, Location loc)
+               MethodGroupExpr ResolveOverloadExtensions (EmitContext ec, ref Arguments arguments, NamespaceEntry ns, Location loc)
                {
                        // Use normal resolve rules
                        MethodGroupExpr mg = base.OverloadResolve (ec, ref arguments, ns != null, loc);
@@ -3278,7 +3173,7 @@ namespace Mono.CSharp {
 
                        e.ExtensionExpression = ExtensionExpression;
                        e.SetTypeArguments (type_arguments);                    
-                       return e.ResolveOverloadExtensions (ec, arguments, e.namespace_entry, loc);
+                       return e.ResolveOverloadExtensions (ec, ref arguments, e.namespace_entry, loc);
                }               
        }
 
@@ -3290,6 +3185,7 @@ namespace Mono.CSharp {
        {
                public interface IErrorHandler
                {
+                       bool AmbiguousCall (MethodBase ambiguous);
                        bool NoExactMatch (EmitContext ec, MethodBase method);
                }
 
@@ -3301,6 +3197,7 @@ namespace Mono.CSharp {
                bool identical_type_name;
                bool has_inaccessible_candidates_only;
                Type delegate_type;
+               Type queried_type;
                
                public MethodGroupExpr (MemberInfo [] mi, Type type, Location l)
                        : this (type, l)
@@ -3337,16 +3234,13 @@ namespace Mono.CSharp {
                {
                        this.loc = loc;
                        eclass = ExprClass.MethodGroup;
-                       this.type = type;
+                       this.type = typeof (MethodGroupExpr);
+                       queried_type = type;
                }
 
                public override Type DeclaringType {
                        get {
-                               //
-                               // We assume that the top-level type is in the end
-                               //
-                               return Methods [Methods.Length - 1].DeclaringType;
-                               //return Methods [0].DeclaringType;
+                               return queried_type;
                        }
                }
 
@@ -3514,7 +3408,7 @@ namespace Mono.CSharp {
                ///     false if candidate ain't better
                ///     true  if candidate is better than the current best match
                /// </remarks>
-               static bool BetterFunction (EmitContext ec, ArrayList args, int argument_count,
+               static bool BetterFunction (EmitContext ec, Arguments args, int argument_count,
                        MethodBase candidate, bool candidate_params,
                        MethodBase best, bool best_params)
                {
@@ -3525,7 +3419,11 @@ namespace Mono.CSharp {
                        bool same = true;
                        for (int j = 0, c_idx = 0, b_idx = 0; j < argument_count; ++j, ++c_idx, ++b_idx) 
                        {
-                               Argument a = (Argument) args [j];
+                               Argument a = args [j];
+
+                               // Provided default argument value is never better
+                               if (a.IsDefaultArgument && candidate_params == best_params)
+                                       return false;
 
                                Type ct = candidate_pd.Types [c_idx];
                                Type bt = best_pd.Types [b_idx];
@@ -3602,7 +3500,7 @@ namespace Mono.CSharp {
 
                        if (candidate_param_count != best_param_count)
                                // can only happen if (candidate_params && best_params)
-                               return candidate_param_count > best_param_count;
+                               return candidate_param_count > best_param_count && best_pd.HasParams;
 
                        //
                        // now, both methods have the same number of parameters, and the parameters have the same types
@@ -3701,14 +3599,19 @@ namespace Mono.CSharp {
                        ReportUsageError ();
                }
                
-               public virtual void EmitArguments (EmitContext ec, ArrayList arguments)
+               public void EmitCall (EmitContext ec, Arguments arguments)
                {
-                       Invocation.EmitArguments (ec, arguments, false, null);  
+                       Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);                   
                }
-               
-               public virtual void EmitCall (EmitContext ec, ArrayList arguments)
+
+               void Error_AmbiguousCall (MethodBase ambiguous)
                {
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);                   
+                       if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ambiguous))
+                               return;
+
+                       Report.SymbolRelatedToPreviousError (best_candidate);
+                       Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
+                               TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate));
                }
 
                protected virtual void Error_InvalidArguments (EmitContext ec, Location loc, int idx, MethodBase method,
@@ -3725,7 +3628,10 @@ namespace Mono.CSharp {
                                }
                                Report.Error (1950, loc, "The best overloaded collection initalizer method `{0}' has some invalid arguments",
                                          TypeManager.CSharpSignature (method));
-                       } else if (delegate_type == null) {
+                       } else if (TypeManager.IsDelegateType (method.DeclaringType)) {
+                               Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
+                                       TypeManager.CSharpName (method.DeclaringType));
+                       } else {
                                Report.SymbolRelatedToPreviousError (method);
                                if (emg != null) {
                                        Report.Error (1928, loc,
@@ -3736,9 +3642,7 @@ namespace Mono.CSharp {
                                        Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
                                                TypeManager.CSharpSignature (method));
                                }
-                       } else
-                               Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
-                                       TypeManager.CSharpName (delegate_type));
+                       }
 
                        Parameter.Modifier mod = idx >= expected_par.Count ? 0 : expected_par.FixedParameters [idx].ModFlags;
 
@@ -3776,6 +3680,12 @@ namespace Mono.CSharp {
                        Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
                                Name, TypeManager.CSharpName (target));
                }
+
+               void Error_ArgumentCountWrong (int arg_count)
+               {
+                       Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
+                                     Name, arg_count.ToString ());
+               }
                
                protected virtual int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
                {
@@ -3796,21 +3706,101 @@ namespace Mono.CSharp {
                /// 0 = the best, int.MaxValue = the worst
                ///
                public int IsApplicable (EmitContext ec,
-                                                ArrayList arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
+                                               ref Arguments arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
                {
                        MethodBase candidate = method;
 
                        AParametersCollection pd = TypeManager.GetParameterData (candidate);
                        int param_count = GetApplicableParametersCount (candidate, pd);
+                       int optional_count = 0;
 
                        if (arg_count != param_count) {
-                               if (!pd.HasParams)
-                                       return int.MaxValue - 10000 + Math.Abs (arg_count - param_count);
-                               if (arg_count < param_count - 1)
-                                       return int.MaxValue - 10000 + Math.Abs (arg_count - param_count);
-                                       
+                               for (int i = 0; i < pd.Count; ++i) {
+                                       if (pd.FixedParameters [i].HasDefaultValue) {
+                                               optional_count = pd.Count - i;
+                                               break;
+                                       }
+                               }
+
+                               int args_gap = Math.Abs (arg_count - param_count);
+                               if (optional_count != 0) {
+                                       if (args_gap > optional_count)
+                                               return int.MaxValue - 10000 + args_gap - optional_count;
+
+                                       // Readjust expected number when params used
+                                       if (pd.HasParams) {
+                                               optional_count--;
+                                               if (arg_count < param_count)
+                                                       param_count--;
+                                       }
+                               } else if (arg_count != param_count) {
+                                       if (!pd.HasParams)
+                                               return int.MaxValue - 10000 + args_gap;
+                                       if (arg_count < param_count - 1)
+                                               return int.MaxValue - 10000 + args_gap;
+                               }
+
                                // Initialize expanded form of a method with 1 params parameter
                                params_expanded_form = param_count == 1 && pd.HasParams;
+
+                               // Resize to fit optional arguments
+                               if (optional_count != 0) {
+                                       Arguments resized;
+                                       if (arguments == null) {
+                                               resized = new Arguments (optional_count);
+                                       } else {
+                                               resized = new Arguments (param_count);
+                                               resized.AddRange (arguments);
+                                       }
+
+                                       for (int i = arg_count; i < param_count; ++i)
+                                               resized.Add (null);
+                                       arguments = resized;
+                               }
+                       }
+
+                       if (arg_count > 0) {
+                               //
+                               // Shuffle named arguments to the right positions if there are any
+                               //
+                               if (arguments [arg_count - 1] is NamedArgument) {
+                                       arg_count = arguments.Count;
+
+                                       for (int i = 0; i < arg_count; ++i) {
+                                               bool arg_moved = false;
+                                               while (true) {
+                                                       NamedArgument na = arguments[i] as NamedArgument;
+                                                       if (na == null)
+                                                               break;
+
+                                                       int index = pd.GetParameterIndexByName (na.Name.Value);
+
+                                                       // Named parameter not found or already reordered
+                                                       if (index <= i)
+                                                               break;
+
+                                                       // When using parameters which should not be available to the user
+                                                       if (index >= param_count)
+                                                               break;
+
+                                                       if (!arg_moved) {
+                                                               arguments.MarkReorderedArgument (na);
+                                                               arg_moved = true;
+                                                       }
+
+                                                       Argument temp = arguments[index];
+                                                       arguments[index] = arguments[i];
+                                                       arguments[i] = temp;
+
+                                                       if (temp == null)
+                                                               break;
+                                               }
+                                       }
+                               } else {
+                                       arg_count = arguments.Count;
+                               }
+                       } else if (arguments != null) {
+                               arg_count = arguments.Count;
                        }
 
 #if GMCS_SOURCE
@@ -3842,7 +3832,7 @@ namespace Mono.CSharp {
                                if (type_arguments != null)
                                        return int.MaxValue - 15000;
                        }
-#endif                 
+#endif
 
                        //
                        // 2. Each argument has to be implicitly convertible to method parameter
@@ -3851,32 +3841,34 @@ namespace Mono.CSharp {
                        Parameter.Modifier p_mod = 0;
                        Type pt = null;
                        for (int i = 0; i < arg_count; i++) {
-                               Argument a = (Argument) arguments [i];
-                               Parameter.Modifier a_mod = a.Modifier &
-                                       ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
-
-                               if (p_mod != Parameter.Modifier.PARAMS) {
-                                       p_mod = pd.FixedParameters [i].ModFlags & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
+                               Argument a = arguments [i];
+                               if (a == null) {
+                                       if (!pd.FixedParameters [i].HasDefaultValue)
+                                               throw new InternalErrorException ();
 
-                                       if (p_mod == Parameter.Modifier.ARGLIST) {
-                                               if (a.Type == TypeManager.runtime_argument_handle_type)
-                                                       continue;
+                                       Expression e = pd.FixedParameters [i].DefaultValue as Constant;
+                                       if (e == null)
+                                               e = new DefaultValueExpression (new TypeExpression (pd.Types [i], loc), loc).Resolve (ec);
 
-                                               p_mod = 0;
-                                       }
+                                       arguments [i] = new Argument (e, Argument.AType.Default);
+                                       continue;
+                               }
 
+                               if (p_mod != Parameter.Modifier.PARAMS) {
+                                       p_mod = pd.FixedParameters [i].ModFlags & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
                                        pt = pd.Types [i];
                                } else {
                                        params_expanded_form = true;
                                }
 
+                               Parameter.Modifier a_mod = a.Modifier & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
                                int score = 1;
                                if (!params_expanded_form)
                                        score = IsArgumentCompatible (ec, a_mod, a, p_mod & ~Parameter.Modifier.PARAMS, pt);
 
                                if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && delegate_type == null) {
                                        // It can be applicable in expanded form
-                                       score = IsArgumentCompatible (ec, a_mod, a, 0, pt.GetElementType ());
+                                       score = IsArgumentCompatible (ec, a_mod, a, 0, TypeManager.GetElementType (pt));
                                        if (score == 0)
                                                params_expanded_form = true;
                                }
@@ -3889,7 +3881,7 @@ namespace Mono.CSharp {
                        }
                        
                        if (arg_count != param_count)
-                               params_expanded_form = true;                    
+                               params_expanded_form = true;    
                        
                        return 0;
                }
@@ -3901,18 +3893,16 @@ namespace Mono.CSharp {
                        //
                        if (arg_mod != 0 || param_mod != 0) {
                                if (TypeManager.HasElementType (parameter))
-                                       parameter = parameter.GetElementType ();
+                                       parameter = TypeManager.GetElementType (parameter);
 
                                Type a_type = argument.Type;
                                if (TypeManager.HasElementType (a_type))
-                                       a_type = a_type.GetElementType ();
+                                       a_type = TypeManager.GetElementType (a_type);
 
                                if (a_type != parameter)
                                        return 2;
                        } else {
-                               if (delegate_type != null ?
-                                       !Delegate.IsTypeCovariant (argument.Expr, parameter) :
-                                       !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+                               if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
                                        return 2;
                        }
 
@@ -4039,12 +4029,11 @@ namespace Mono.CSharp {
                ///            that is the best match of me on Arguments.
                ///
                /// </summary>
-               public virtual MethodGroupExpr OverloadResolve (EmitContext ec, ref ArrayList Arguments,
+               public virtual MethodGroupExpr OverloadResolve (EmitContext ec, ref Arguments Arguments,
                        bool may_fail, Location loc)
                {
                        bool method_params = false;
                        Type applicable_type = null;
-                       int arg_count = 0;
                        ArrayList candidates = new ArrayList (2);
                        ArrayList candidate_overrides = null;
 
@@ -4056,9 +4045,10 @@ namespace Mono.CSharp {
                        // false is normal form, true is expanded form
                        //
                        Hashtable candidate_to_form = null;
+                       Hashtable candidates_expanded = null;
+                       Arguments candidate_args = Arguments;
 
-                       if (Arguments != null)
-                               arg_count = Arguments.Count;
+                       int arg_count = Arguments != null ? Arguments.Count : 0;
 
                        if (RootContext.Version == LanguageVersion.ISO_1 && Name == "Invoke" && TypeManager.IsDelegateType (DeclaringType)) {
                                if (!may_fail)
@@ -4119,7 +4109,7 @@ namespace Mono.CSharp {
                                // Check if candidate is applicable (section 14.4.2.1)
                                //
                                bool params_expanded_form = false;
-                               int candidate_rate = IsApplicable (ec, Arguments, arg_count, ref Methods [i], ref params_expanded_form);
+                               int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref Methods [i], ref params_expanded_form);
 
                                if (candidate_rate < best_candidate_rate) {
                                        best_candidate_rate = candidate_rate;
@@ -4132,6 +4122,14 @@ namespace Mono.CSharp {
                                        MethodBase candidate = Methods [i];
                                        candidate_to_form [candidate] = candidate;
                                }
+                               
+                               if (candidate_args != Arguments) {
+                                       if (candidates_expanded == null)
+                                               candidates_expanded = new Hashtable (2);
+
+                                       candidates_expanded.Add (Methods [i], candidate_args);
+                                       candidate_args = Arguments;
+                               }
 
                                if (candidate_rate != 0 || has_inaccessible_candidates_only) {
                                        if (msg_recorder != null)
@@ -4183,10 +4181,8 @@ namespace Mono.CSharp {
                                // return error info about the closest match
                                //
                                if (best_candidate != null) {
-                                       if (CustomErrorHandler != null) {
-                                               if (CustomErrorHandler.NoExactMatch (ec, best_candidate))
-                                                       return null;
-                                       }
+                                       if (CustomErrorHandler != null && !has_inaccessible_candidates_only && CustomErrorHandler.NoExactMatch (ec, best_candidate))
+                                               return null;
 
                                        AParametersCollection pd = TypeManager.GetParameterData (best_candidate);
                                        bool cand_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
@@ -4222,8 +4218,9 @@ namespace Mono.CSharp {
                                                                // base class (CS1540).  If the qualifier_type is a base of the
                                                                // ec.ContainerType and the lookup succeeds with the latter one,
                                                                // then we are in this situation.
-                                                               Error_CannotAccessProtected (loc, best_candidate, type, ec.ContainerType);
+                                                               Error_CannotAccessProtected (loc, best_candidate, queried_type, ec.ContainerType);
                                                        } else {
+                                                               Report.SymbolRelatedToPreviousError (best_candidate);
                                                                ErrorIsInaccesible (loc, GetSignatureForError ());
                                                        }
                                                }
@@ -4233,6 +4230,8 @@ namespace Mono.CSharp {
 
                                                if (has_inaccessible_candidates_only)
                                                        return null;
+
+                                               throw new InternalErrorException ("VerifyArgumentsCompat didn't find any problem with rejected candidate " + best_candidate);
                                        }
                                }
 
@@ -4240,13 +4239,12 @@ namespace Mono.CSharp {
                                // We failed to find any method with correct argument count
                                //
                                if (Name == ConstructorInfo.ConstructorName) {
-                                       Report.SymbolRelatedToPreviousError (type);
+                                       Report.SymbolRelatedToPreviousError (queried_type);
                                        Report.Error (1729, loc,
                                                "The type `{0}' does not contain a constructor that takes `{1}' arguments",
-                                               TypeManager.CSharpName (type), arg_count);
+                                               TypeManager.CSharpName (queried_type), arg_count);
                                } else {
-                                       Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
-                                               Name, arg_count.ToString ());
+                                       Error_ArgumentCountWrong (arg_count);
                                }
                                 
                                return null;
@@ -4310,6 +4308,15 @@ namespace Mono.CSharp {
                        best_candidate = (MethodBase) candidates [0];
                        method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
 
+                       //
+                       // TODO: Broken inverse order of candidates logic does not work with optional
+                       // parameters used for method overrides and I am not going to fix it for SRE
+                       //
+                       if (candidates_expanded != null && candidates_expanded.Contains (best_candidate)) {
+                               candidate_args = (Arguments) candidates_expanded [best_candidate];
+                               arg_count = candidate_args.Count;
+                       }
+
                        for (int ix = 1; ix < candidate_top; ix++) {
                                MethodBase candidate = (MethodBase) candidates [ix];
 
@@ -4318,7 +4325,7 @@ namespace Mono.CSharp {
 
                                bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
 
-                               if (BetterFunction (ec, Arguments, arg_count, 
+                               if (BetterFunction (ec, candidate_args, arg_count, 
                                        candidate, cand_params,
                                        best_candidate, method_params)) {
                                        best_candidate = candidate;
@@ -4337,7 +4344,7 @@ namespace Mono.CSharp {
                                        continue;
 
                                bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
-                               if (!BetterFunction (ec, Arguments, arg_count,
+                               if (!BetterFunction (ec, candidate_args, arg_count,
                                        best_candidate, method_params,
                                        candidate, cand_params)) 
                                {
@@ -4348,9 +4355,7 @@ namespace Mono.CSharp {
                        }
 
                        if (ambiguous != null) {
-                               Report.SymbolRelatedToPreviousError (best_candidate);
-                               Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
-                                       TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate));
+                               Error_AmbiguousCall (ambiguous);
                                return this;
                        }
 
@@ -4400,7 +4405,7 @@ namespace Mono.CSharp {
                        // necessary etc. and return if everything is
                        // all right
                        //
-                       if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate,
+                       if (!VerifyArgumentsCompat (ec, ref candidate_args, arg_count, best_candidate,
                                method_params, may_fail, loc))
                                return null;
 
@@ -4408,11 +4413,9 @@ namespace Mono.CSharp {
                                return null;
 
                        MethodBase the_method = TypeManager.DropGenericMethodArguments (best_candidate);
-#if GMCS_SOURCE
-                       if (the_method.IsGenericMethodDefinition &&
+                       if (TypeManager.IsGenericMethodDefinition (the_method) &&
                            !ConstraintChecker.CheckConstraints (ec, the_method, best_candidate, loc))
                                return null;
-#endif
 
                        //
                        // Check ObsoleteAttribute on the best method
@@ -4425,6 +4428,7 @@ namespace Mono.CSharp {
                        if (data != null)
                                data.SetMemberIsUsed ();
 
+                       Arguments = candidate_args;
                        return this;
                }
                
@@ -4433,12 +4437,13 @@ namespace Mono.CSharp {
                        type_arguments = ta;
                }
 
-               public bool VerifyArgumentsCompat (EmitContext ec, ref ArrayList arguments,
+               public bool VerifyArgumentsCompat (EmitContext ec, ref Arguments arguments,
                                                          int arg_count, MethodBase method,
                                                          bool chose_params_expanded,
                                                          bool may_fail, Location loc)
                {
                        AParametersCollection pd = TypeManager.GetParameterData (method);
+                       int param_count = GetApplicableParametersCount (method, pd);
 
                        int errors = Report.Errors;
                        Parameter.Modifier p_mod = 0;
@@ -4449,18 +4454,12 @@ namespace Mono.CSharp {
                        bool has_unsafe_arg = false;
 
                        for (; a_idx < arg_count; a_idx++, ++a_pos) {
-                               a = (Argument) arguments [a_idx];
+                               a = arguments [a_idx];
                                if (p_mod != Parameter.Modifier.PARAMS) {
                                        p_mod = pd.FixedParameters [a_idx].ModFlags;
                                        pt = pd.Types [a_idx];
                                        has_unsafe_arg |= pt.IsPointer;
 
-                                       if (p_mod == Parameter.Modifier.ARGLIST) {
-                                               if (a.Type != TypeManager.runtime_argument_handle_type)
-                                                       break;
-                                               continue;
-                                       }
-
                                        if (p_mod == Parameter.Modifier.PARAMS) {
                                                if (chose_params_expanded) {
                                                        params_initializers = new ArrayList (arg_count - a_idx);
@@ -4480,8 +4479,38 @@ namespace Mono.CSharp {
                                                break;
 
                                        continue;
+                               } else {
+                                       NamedArgument na = a as NamedArgument;
+                                       if (na != null) {
+                                               int name_index = pd.GetParameterIndexByName (na.Name.Value);
+                                               if (name_index < 0 || name_index >= param_count) {
+                                                       if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType)) {
+                                                               Report.SymbolRelatedToPreviousError (DeclaringType);
+                                                               Report.Error (1746, na.Name.Location,
+                                                                       "The delegate `{0}' does not contain a parameter named `{1}'",
+                                                                       TypeManager.CSharpName (DeclaringType), na.Name.Value);
+                                                       } else {
+                                                               Report.SymbolRelatedToPreviousError (best_candidate);
+                                                               Report.Error (1739, na.Name.Location,
+                                                                       "The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
+                                                                       TypeManager.CSharpSignature (method), na.Name.Value);
+                                                       }
+                                               } else if (arguments[name_index] != a) {
+                                                       if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType))
+                                                               Report.SymbolRelatedToPreviousError (DeclaringType);
+                                                       else
+                                                               Report.SymbolRelatedToPreviousError (best_candidate);
+
+                                                       Report.Error (1744, na.Name.Location,
+                                                               "Named argument `{0}' cannot be used for a parameter which has positional argument specified",
+                                                               na.Name.Value);
+                                               }
+                                       }
                                }
 
+                               if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt))
+                                       break;
+
                                Expression conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc);
                                if (conv == null)
                                        break;
@@ -4502,45 +4531,52 @@ namespace Mono.CSharp {
                                a.Expr = conv;
                        }
 
+                       if (a_idx != arg_count) {
+                               if (!may_fail && Report.Errors == errors) {
+                                       if (CustomErrorHandler != null)
+                                               CustomErrorHandler.NoExactMatch (ec, best_candidate);
+                                       else
+                                               Error_InvalidArguments (ec, loc, a_pos, method, a, pd, pt);
+                               }
+                               return false;
+                       }
+
                        //
                        // Fill not provided arguments required by params modifier
                        //
-                       if (params_initializers == null && pd.HasParams && arg_count < pd.Count && a_idx + 1 == pd.Count) {
+                       if (params_initializers == null && pd.HasParams && arg_count + 1 == param_count) {
                                if (arguments == null)
-                                       arguments = new ArrayList (1);
+                                       arguments = new Arguments (1);
 
-                               pt = pd.Types [GetApplicableParametersCount (method, pd) - 1];
+                               pt = pd.Types [param_count - 1];
                                pt = TypeManager.GetElementType (pt);
                                has_unsafe_arg |= pt.IsPointer;
                                params_initializers = new ArrayList (0);
                        }
 
-                       if (a_idx == arg_count) {
-                               //
-                               // Append an array argument with all params arguments
-                               //
-                               if (params_initializers != null) {
-                                       arguments.Add (new Argument (
-                                               new ArrayCreation (new TypeExpression (pt, loc), "[]",
-                                               params_initializers, loc).Resolve (ec)));
-                               }
-
-                               if (has_unsafe_arg && !ec.InUnsafe) {
-                                       if (!may_fail)
-                                               UnsafeError (loc);
-                                       return false;
-                               }
+                       //
+                       // Append an array argument with all params arguments
+                       //
+                       if (params_initializers != null) {
+                               arguments.Add (new Argument (
+                                                      new ArrayCreation (new TypeExpression (pt, loc), "[]",
+                                                                         params_initializers, loc).Resolve (ec)));
+                               arg_count++;
+                       }
 
-                               return true;
+                       if (arg_count < param_count) {
+                               if (!may_fail)
+                                       Error_ArgumentCountWrong (arg_count);
+                               return false;
                        }
 
-                       if (!may_fail && Report.Errors == errors) {
-                               if (CustomErrorHandler != null)
-                                       CustomErrorHandler.NoExactMatch (ec, best_candidate);
-                               else
-                                       Error_InvalidArguments (ec, loc, a_pos, method, a, pd, pt);
+                       if (has_unsafe_arg && !ec.InUnsafe) {
+                               if (!may_fail)
+                                       UnsafeError (loc);
+                               return false;
                        }
-                       return false;
+
+                       return true;
                }
        }
 
@@ -4628,6 +4664,11 @@ namespace Mono.CSharp {
                LocalTemporary temp;
                bool prepared;
                
+               protected FieldExpr (Location l)
+               {
+                       loc = l;
+               }
+               
                public FieldExpr (FieldInfo fi, Location l)
                {
                        FieldInfo = fi;
@@ -4707,9 +4748,10 @@ namespace Mono.CSharp {
                                instance = InstanceExpression.CreateExpressionTree (ec);
                        }
 
-                       ArrayList args = new ArrayList (2);
-                       args.Add (new Argument (instance));
-                       args.Add (new Argument (CreateTypeOfExpression ()));
+                       Arguments args = Arguments.CreateForExpressionTree (ec, null,
+                               instance,
+                               CreateTypeOfExpression ());
+
                        return CreateExpressionFactoryCall ("Field", args);
                }
 
@@ -4743,11 +4785,15 @@ namespace Mono.CSharp {
                                        using (ec.With (EmitContext.Flags.DoFlowAnalysis, false)) {
                                                Expression right_side =
                                                        out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
-                                               InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side, loc);
+
+                                               if (InstanceExpression != EmptyExpression.Null)
+                                                       InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
                                        }
                                } else {
                                        ResolveFlags rf = ResolveFlags.VariableOrValue | ResolveFlags.DisableFlowAnalysis;
-                                       InstanceExpression = InstanceExpression.Resolve (ec, rf);
+
+                                       if (InstanceExpression != EmptyExpression.Null)
+                                               InstanceExpression = InstanceExpression.Resolve (ec, rf);
                                }
 
                                if (InstanceExpression == null)
@@ -4851,7 +4897,7 @@ namespace Mono.CSharp {
                        if (var != null && var.VariableInfo != null)
                                var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name);
 
-                       bool lvalue_instance = !FieldInfo.IsStatic && FieldInfo.DeclaringType.IsValueType;
+                       bool lvalue_instance = !FieldInfo.IsStatic && TypeManager.IsValueType (FieldInfo.DeclaringType);
                        bool out_access = right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess;
 
                        Expression e = DoResolve (ec, lvalue_instance, out_access);
@@ -4899,7 +4945,7 @@ namespace Mono.CSharp {
 
                bool is_marshal_by_ref ()
                {
-                       return !IsStatic && Type.IsValueType && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type);
+                       return !IsStatic && TypeManager.IsStruct (Type) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type);
                }
 
                public override void CheckMarshalByRefAccess (EmitContext ec)
@@ -4922,7 +4968,11 @@ namespace Mono.CSharp {
                                // A variable of the form V.I is fixed when V is a fixed variable of a struct type
                                //
                                IVariableReference variable = InstanceExpression as IVariableReference;
-                               return variable != null && InstanceExpression.Type.IsValueType && variable.IsFixed;
+                               if (variable != null)
+                                       return TypeManager.IsStruct (InstanceExpression.Type) && variable.IsFixed;
+
+                               IFixedExpression fe = InstanceExpression as IFixedExpression;
+                               return fe != null && fe.IsFixed;
                        }
                }
 
@@ -4970,15 +5020,21 @@ namespace Mono.CSharp {
                                if (!prepared)
                                        EmitInstance (ec, false);
 
-                               IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
-                               if (ff != null) {
-                                       ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
-                                       ig.Emit (OpCodes.Ldflda, ff.Element);
+                               // Optimization for build-in types
+                               // TODO: Iterators don't set current container
+                               if (TypeManager.IsStruct (type) && type == ec.DeclContainer.TypeBuilder && ec.CurrentIterator == null) {
+                                       LoadFromPtr (ig, type);
                                } else {
-                                       if (is_volatile)
-                                               ig.Emit (OpCodes.Volatile);
+                                       IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
+                                       if (ff != null) {
+                                               ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
+                                               ig.Emit (OpCodes.Ldflda, ff.Element);
+                                       } else {
+                                               if (is_volatile)
+                                                       ig.Emit (OpCodes.Volatile);
 
-                                       ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ());
+                                               ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ());
+                                       }
                                }
                        }
 
@@ -5177,9 +5233,9 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args;
+                       Arguments args;
                        if (IsSingleDimensionalArrayLength ()) {
-                               args = new ArrayList (1);
+                               args = new Arguments (1);
                                args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
                                return CreateExpressionFactoryCall ("ArrayLength", args);
                        }
@@ -5189,7 +5245,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       args = new ArrayList (2);
+                       args = new Arguments (2);
                        if (InstanceExpression == null)
                                args.Add (new Argument (new NullLiteral (loc)));
                        else
@@ -5302,7 +5358,7 @@ namespace Mono.CSharp {
 
                        InstanceExpression = InstanceExpression.DoResolve (ec);
                        if (lvalue_instance && InstanceExpression != null)
-                               InstanceExpression = InstanceExpression.ResolveLValue (ec, EmptyExpression.LValueMemberAccess, loc);
+                               InstanceExpression = InstanceExpression.ResolveLValue (ec, EmptyExpression.LValueMemberAccess);
 
                        if (InstanceExpression == null)
                                return false;
@@ -5438,7 +5494,7 @@ namespace Mono.CSharp {
                override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
                        if (right_side == EmptyExpression.OutAccess) {
-                               if (ec.CurrentBlock.Toplevel.GetTransparentIdentifier (PropertyInfo.Name) != null) {
+                               if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
                                        Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
                                            PropertyInfo.Name);
                                } else {
@@ -5462,7 +5518,7 @@ namespace Mono.CSharp {
                                if (getter == null)
                                        return null;
 
-                               if (ec.CurrentBlock.Toplevel.GetTransparentIdentifier (PropertyInfo.Name) != null) {
+                               if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
                                        Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
                                                PropertyInfo.Name);
                                } else {
@@ -5492,7 +5548,7 @@ namespace Mono.CSharp {
                                return null;
                        }
                        
-                       if (!InstanceResolve (ec, PropertyInfo.DeclaringType.IsValueType, must_do_cs1540_check))
+                       if (!InstanceResolve (ec, TypeManager.IsStruct (PropertyInfo.DeclaringType), must_do_cs1540_check))
                                return null;
                        
                        //
@@ -5574,8 +5630,8 @@ namespace Mono.CSharp {
                                my_source = temp;
                        }
 
-                       ArrayList args = new ArrayList (1);
-                       args.Add (new Argument (my_source, Argument.AType.Expression));
+                       Arguments args = new Arguments (1);
+                       args.Add (new Argument (my_source));
                        
                        Invocation.EmitCall (ec, IsBase, InstanceExpression, setter, args, loc, false, prepared);
                        
@@ -5662,7 +5718,7 @@ namespace Mono.CSharp {
                                        if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.IsInCompoundAssignment)
                                                Error_AssignmentEventOnly ();
                                        
-                                       FieldExpr ml = new FieldExpr (mi.FieldBuilder, loc);
+                                       FieldExpr ml = new FieldExpr (mi.BackingField.FieldBuilder, loc);
 
                                        InstanceExpression = null;
                                
@@ -5785,8 +5841,8 @@ namespace Mono.CSharp {
 
                public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
                {
-                       ArrayList args = new ArrayList (1);
-                       args.Add (new Argument (source, Argument.AType.Expression));
+                       Arguments args = new Arguments (1);
+                       args.Add (new Argument (source));
                        Invocation.EmitCall (ec, IsBase, InstanceExpression, is_add ? add_accessor : remove_accessor, args, loc);
                }
        }
@@ -5844,8 +5900,9 @@ namespace Mono.CSharp {
                        EmitAssign (ec, source, false, false);
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return li.HoistedVariableReference; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return li.HoistedVariableReference;
                }
 
                public override bool IsFixed {