2009-06-29 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / ecore.cs
index 85597887085fd3139aa0db70334511b2f41b66d1..cc6d1bdd23712d23aff6f9952fc7fea66767edfb 100644 (file)
@@ -31,6 +31,7 @@ namespace Mono.CSharp {
                Variable,
                Namespace,
                Type,
+               TypeParameter,
                MethodGroup,
                PropertyAccess,
                EventAccess,
@@ -48,24 +49,26 @@ namespace Mono.CSharp {
                VariableOrValue         = 1,
 
                // Returns a type expression.
-               Type                    = 2,
+               Type                    = 1 << 1,
 
                // Returns a method group.
-               MethodGroup             = 4,
+               MethodGroup             = 1 << 2,
+
+               TypeParameter   = 1 << 3,
 
                // Mask of all the expression class flags.
-               MaskExprClass           = 7,
+               MaskExprClass = VariableOrValue | Type | MethodGroup | TypeParameter,
 
                // Disable control flow analysis while resolving the expression.
                // This is used when resolving the instance expression of a field expression.
-               DisableFlowAnalysis     = 8,
+               DisableFlowAnalysis     = 1 << 10,
 
                // Set if this is resolving the first part of a MemberAccess.
-               Intermediate            = 16,
+               Intermediate            = 1 << 11,
 
                // Disable control flow analysis _of struct_ while resolving the expression.
                // This is used when resolving the instance expression of a field expression.
-               DisableStructFlowAnalysis       = 32,
+               DisableStructFlowAnalysis       = 1 << 12,
 
        }
 
@@ -100,8 +103,8 @@ namespace Mono.CSharp {
        //
        // An expressions resolved as a direct variable reference
        //
-       public interface IVariableReference {
-               bool IsFixedVariable { get; }
+       public interface IVariableReference : IFixedExpression
+       {
                bool IsHoisted { get; }
                string Name { get; }
                VariableInfo VariableInfo { get; }
@@ -109,6 +112,15 @@ namespace Mono.CSharp {
                void SetHasAddressTaken ();
        }
 
+       //
+       // Implemented by an expression which could be or is always
+       // fixed
+       //
+       public interface IFixedExpression
+       {
+               bool IsFixed { get; }
+       }
+
        /// <remarks>
        ///   Base class for expressions
        /// </remarks>
@@ -270,7 +282,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       ConstructedType ct = te as ConstructedType;
+                       GenericTypeExpr ct = te as GenericTypeExpr;
                        if (ct != null) {
                                // Skip constrains check for overrides and explicit implementations
                                // TODO: they should use different overload
@@ -286,7 +298,7 @@ namespace Mono.CSharp {
 
                        return te;
                }
-
+       
                public TypeExpr ResolveAsBaseTerminal (IResolveContext ec, bool silent)
                {
                        int errors = Report.Errors;
@@ -295,15 +307,14 @@ namespace Mono.CSharp {
 
                        if (fne == null)
                                return null;
-
-                       if (fne.eclass != ExprClass.Type) {
+                               
+                       TypeExpr te = fne as TypeExpr;                          
+                       if (te == null) {
                                if (!silent && errors == Report.Errors)
                                        fne.Error_UnexpectedKind (null, "type", loc);
                                return null;
                        }
 
-                       TypeExpr te = fne as TypeExpr;
-
                        if (!te.CheckAccessLevel (ec.GenericDeclContainer)) {
                                Report.SymbolRelatedToPreviousError (te.Type);
                                ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type));
@@ -352,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)
@@ -425,22 +441,25 @@ namespace Mono.CSharp {
                {
                        get {
                                switch (eclass) {
-                                       case ExprClass.Type:
-                                       case ExprClass.Namespace:
-                                               return ResolveFlags.Type;
-
-                                       case ExprClass.MethodGroup:
-                                               return ResolveFlags.MethodGroup;
-
-                                       case ExprClass.Value:
-                                       case ExprClass.Variable:
-                                       case ExprClass.PropertyAccess:
-                                       case ExprClass.EventAccess:
-                                       case ExprClass.IndexerAccess:
-                                               return ResolveFlags.VariableOrValue;
-
-                                       default:
-                                               throw new InternalErrorException (loc.ToString () + " " +  GetType () + " ExprClass is Invalid after resolve");
+                               case ExprClass.Type:
+                               case ExprClass.Namespace:
+                                       return ResolveFlags.Type;
+                                       
+                               case ExprClass.MethodGroup:
+                                       return ResolveFlags.MethodGroup;
+                                       
+                               case ExprClass.TypeParameter:
+                                       return ResolveFlags.TypeParameter;
+                                       
+                               case ExprClass.Value:
+                               case ExprClass.Variable:
+                               case ExprClass.PropertyAccess:
+                               case ExprClass.EventAccess:
+                               case ExprClass.IndexerAccess:
+                                       return ResolveFlags.VariableOrValue;
+                                       
+                               default:
+                                       throw new InternalErrorException (loc.ToString () + " " +  GetType () + " ExprClass is Invalid after resolve");
                                }
                        }
                }
@@ -517,7 +536,11 @@ namespace Mono.CSharp {
                        if (c != null)
                                return c;
 
-                       Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
+                       if (type != null && TypeManager.IsReferenceType (type))
+                               Const.Error_ConstantCanBeInitializedWithNullOnly (type, loc, mc.GetSignatureForError ());
+                       else
+                               Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
+
                        return null;
                }
 
@@ -529,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;
@@ -558,12 +581,7 @@ namespace Mono.CSharp {
                        if (e.eclass == ExprClass.Invalid)
                                throw new Exception ("Expression " + e + " ExprClass is Invalid after resolve");
 
-                       if (e.eclass == ExprClass.MethodGroup) {
-                               ((MethodGroupExpr) e).ReportUsageError ();
-                               return null;
-                       }
-
-                       if ((e.type == null) && !(e is ConstructedType))
+                       if ((e.type == null) && !(e is GenericTypeExpr))
                                throw new Exception ("Expression " + e + " did not set its type after Resolve");
 
                        return e;
@@ -631,6 +649,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               // TODO: [Obsolete ("Can be removed")]
                protected static ArrayList almost_matched_members = new ArrayList (4);
 
                //
@@ -794,7 +813,6 @@ namespace Mono.CSharp {
                        Expression e;
 
                        int errors = Report.Errors;
-
                        e = MemberLookup (ec.ContainerType, qualifier_type, queried_type, name, mt, bf, loc);
 
                        if (e != null || errors != Report.Errors)
@@ -809,42 +827,6 @@ namespace Mono.CSharp {
                                                       Type queried_type, string name, string class_name,
                                                           MemberTypes mt, BindingFlags bf)
                {
-                       if (almost_matched_members.Count != 0) {
-                               for (int i = 0; i < almost_matched_members.Count; ++i) {
-                                       MemberInfo m = (MemberInfo) almost_matched_members [i];
-                                       for (int j = 0; j < i; ++j) {
-                                               if (m == almost_matched_members [j]) {
-                                                       m = null;
-                                                       break;
-                                               }
-                                       }
-                                       if (m == null)
-                                               continue;
-                                       
-                                       Type declaring_type = m.DeclaringType;
-                                       
-                                       Report.SymbolRelatedToPreviousError (m);
-                                       if (qualifier_type == null) {
-                                               Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
-                                                             TypeManager.CSharpName (m.DeclaringType),
-                                                             TypeManager.CSharpName (container_type));
-                                               
-                                       } else if (qualifier_type != container_type &&
-                                                  TypeManager.IsNestedFamilyAccessible (container_type, declaring_type)) {
-                                               // Although a derived class can access protected members of
-                                               // its base class it cannot do so through an instance of the
-                                               // 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, m, qualifier_type, container_type);
-                                       } else {
-                                               ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (m));
-                                       }
-                               }
-                               almost_matched_members.Clear ();
-                               return null;
-                       }
-
                        MemberInfo[] lookup = null;
                        if (queried_type == null) {
                                class_name = "global::";
@@ -854,9 +836,30 @@ namespace Mono.CSharp {
                                        name, null);
 
                                if (lookup != null) {
-                                       Report.SymbolRelatedToPreviousError (lookup [0]);
-                                       ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (lookup [0]));
-                                       return Error_MemberLookupFailed (lookup);
+                                       Expression e = Error_MemberLookupFailed (queried_type, lookup);
+
+                                       //
+                                       // FIXME: This is still very wrong, it should be done inside
+                                       // OverloadResolve to do correct arguments matching.
+                                       // Requires MemberLookup accessiblity check removal
+                                       //
+                                       if (e == null || (mt & (MemberTypes.Method | MemberTypes.Constructor)) == 0) {
+                                               MemberInfo mi = lookup[0];
+                                               Report.SymbolRelatedToPreviousError (mi);
+                                               if (qualifier_type != null && container_type != null && qualifier_type != container_type &&
+                                                       TypeManager.IsNestedFamilyAccessible (container_type, mi.DeclaringType)) {
+                                                       // Although a derived class can access protected members of
+                                                       // its base class it cannot do so through an instance of the
+                                                       // 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, mi, qualifier_type, container_type);
+                                               } else {
+                                                       ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (mi));
+                                               }
+                                       }
+
+                                       return e;
                                }
 
                                lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
@@ -889,10 +892,10 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       return Error_MemberLookupFailed (lookup);
+                       return Error_MemberLookupFailed (queried_type, lookup);
                }
 
-               protected virtual Expression Error_MemberLookupFailed (MemberInfo[] members)
+               protected virtual Expression Error_MemberLookupFailed (Type type, MemberInfo[] members)
                {
                        for (int i = 0; i < members.Length; ++i) {
                                if (!(members [i] is MethodBase))
@@ -900,7 +903,7 @@ namespace Mono.CSharp {
                        }
 
                        // By default propagate the closest candidates upwards
-                       return new MethodGroupExpr (members, type, loc);
+                       return new MethodGroupExpr (members, type, loc, true);
                }
 
                protected virtual void Error_NegativeArrayIndex (Location loc)
@@ -939,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);
 
@@ -983,26 +986,28 @@ namespace Mono.CSharp {
                {
                        get {
                                switch (eclass){
-                                       case ExprClass.Invalid:
-                                               return "Invalid";
-                                       case ExprClass.Value:
-                                               return "value";
-                                       case ExprClass.Variable:
-                                               return "variable";
-                                       case ExprClass.Namespace:
-                                               return "namespace";
-                                       case ExprClass.Type:
-                                               return "type";
-                                       case ExprClass.MethodGroup:
-                                               return "method group";
-                                       case ExprClass.PropertyAccess:
-                                               return "property access";
-                                       case ExprClass.EventAccess:
-                                               return "event access";
-                                       case ExprClass.IndexerAccess:
-                                               return "indexer access";
-                                       case ExprClass.Nothing:
-                                               return "null";
+                               case ExprClass.Invalid:
+                                       return "Invalid";
+                               case ExprClass.Value:
+                                       return "value";
+                               case ExprClass.Variable:
+                                       return "variable";
+                               case ExprClass.Namespace:
+                                       return "namespace";
+                               case ExprClass.Type:
+                                       return "type";
+                               case ExprClass.MethodGroup:
+                                       return "method group";
+                               case ExprClass.PropertyAccess:
+                                       return "property access";
+                               case ExprClass.EventAccess:
+                                       return "event access";
+                               case ExprClass.IndexerAccess:
+                                       return "indexer access";
+                               case ExprClass.Nothing:
+                                       return "null";
+                               case ExprClass.TypeParameter:
+                                       return "type parameter";
                                }
                                throw new Exception ("Should not happen");
                        }
@@ -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);
@@ -1174,14 +1179,20 @@ namespace Mono.CSharp {
                {
                        Report.SymbolRelatedToPreviousError (type);
                        if (ec.CurrentInitializerVariable != null) {
-                               Report.Error (1918, loc, "Members of a value type property `{0}' cannot be assigned with an object initializer",
-                                       GetSignatureForError ());
+                               Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+                                       TypeManager.CSharpName (type), GetSignatureForError ());
                        } else {
                                Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
                                        GetSignatureForError ());
                        }
                }
 
+               public void Error_ExpressionCannotBeGeneric (Location loc)
+               {
+                       Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
+                               ExprClassName, GetSignatureForError ());
+               }
+
                //
                // Converts `source' to an int, uint, long or ulong.
                //
@@ -1256,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);
                }
@@ -1353,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)));
 
@@ -1383,6 +1394,7 @@ namespace Mono.CSharp {
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
+                       type = storey.MutateType (type);
                        child.MutateHoistedGenericType (storey);
                }
 
@@ -1426,19 +1438,23 @@ namespace Mono.CSharp {
                }
        }
 
-       /// <summary>
-       ///    Performs a cast using an operator (op_Explicit or op_Implicit)
-       /// </summary>
+       //
+       // Used for predefined class library user casts (no obsolete check, etc.)
+       //
        public class OperatorCast : TypeCast {
                MethodInfo conversion_operator;
-               bool find_explicit;
                        
-               public OperatorCast (Expression child, Type target_type) : this (child, target_type, false) {}
+               public OperatorCast (Expression child, Type target_type) 
+                       : this (child, target_type, false)
+               {
+               }
 
                public OperatorCast (Expression child, Type target_type, bool find_explicit)
                        : base (child, target_type)
                {
-                       this.find_explicit = find_explicit;
+                       conversion_operator = GetConversionOperator (find_explicit);
+                       if (conversion_operator == null)
+                               throw new InternalErrorException ("Outer conversion routine is out of sync");
                }
 
                // Returns the implicit operator that converts from
@@ -1458,75 +1474,34 @@ namespace Mono.CSharp {
                        }
                        
                        foreach (MethodInfo oper in mi) {
-                               ParameterData pd = TypeManager.GetParameterData (oper);
+                               AParametersCollection pd = TypeManager.GetParameterData (oper);
 
-                               if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
+                               if (pd.Types [0] == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
                                        return oper;
                        }
 
                        return null;
-
-
                }
+
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        child.Emit (ec);
-                       conversion_operator = GetConversionOperator (find_explicit);
-
-                       if (conversion_operator == null)
-                               throw new InternalErrorException ("Outer conversion routine is out of sync");
-
-                       ig.Emit (OpCodes.Call, conversion_operator);
+                       ec.ig.Emit (OpCodes.Call, conversion_operator);
                }
-               
        }
        
        /// <summary>
        ///     This is a numeric cast to a Decimal
        /// </summary>
-       public class CastToDecimal : TypeCast {
-               MethodInfo conversion_operator;
-
+       public class CastToDecimal : OperatorCast {
                public CastToDecimal (Expression child)
                        : this (child, false)
                {
                }
 
                public CastToDecimal (Expression child, bool find_explicit)
-                       : base (child, TypeManager.decimal_type)
-               {
-                       conversion_operator = GetConversionOperator (find_explicit);
-
-                       if (conversion_operator == null)
-                               throw new InternalErrorException ("Outer conversion routine is out of sync");
-               }
-
-               // Returns the implicit operator that converts from
-               // 'child.Type' to System.Decimal.
-               MethodInfo GetConversionOperator (bool find_explicit)
-               {
-                       string operator_name = find_explicit ? "op_Explicit" : "op_Implicit";
-                       
-                       MemberInfo [] mi = TypeManager.MemberLookup (type, type, type, MemberTypes.Method,
-                               BindingFlags.Static | BindingFlags.Public, operator_name, null);
-
-                       foreach (MethodInfo oper in mi) {
-                               ParameterData pd = TypeManager.GetParameterData (oper);
-
-                               if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
-                                       return oper;
-                       }
-
-                       return null;
-               }
-               public override void Emit (EmitContext ec)
+                       : base (child, TypeManager.decimal_type, find_explicit)
                {
-                       ILGenerator ig = ec.ig;
-                       child.Emit (ec);
-
-                       ig.Emit (OpCodes.Call, conversion_operator);
                }
        }
 
@@ -1556,8 +1531,8 @@ namespace Mono.CSharp {
 
                                operators = new System.Collections.Specialized.HybridDictionary ();
                                foreach (MethodInfo oper in all_oper) {
-                                       ParameterData pd = TypeManager.GetParameterData (oper);
-                                       if (pd.ParameterType (0) == TypeManager.decimal_type)
+                                       AParametersCollection pd = TypeManager.GetParameterData (oper);
+                                       if (pd.Types [0] == TypeManager.decimal_type)
                                                operators.Add (TypeManager.TypeToCoreType (oper.ReturnType), oper);
                                }
                        }
@@ -1610,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 ();
 
@@ -1642,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)
@@ -1662,6 +1644,11 @@ namespace Mono.CSharp {
                                return null;
                        return child.ConvertImplicitly (target_type);
                }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       child.MutateHoistedGenericType (storey);
+               }
        }
 
 
@@ -1725,12 +1712,24 @@ namespace Mono.CSharp {
                                return Child.GetValue ();
                        }
 
+#if MS_COMPATIBLE
+                       // Small workaround for big problem
+                       // System.Enum.ToObject cannot be called on dynamic types
+                       // EnumBuilder has to be used, but we cannot use EnumBuilder
+                       // because it does not properly support generics
+                       //
+                       // This works only sometimes
+                       //
+                       if (type.Module == RootContext.ToplevelTypes.Builder)
+                               return Child.GetValue ();
+#endif
+
                        return System.Enum.ToObject (type, Child.GetValue ());
                }
                
                public override string AsString ()
                {
-                       return TypeManager.CSharpEnumValue (type, Child.GetValue ());
+                       return Child.AsString ();
                }
 
                public override Constant Increment()
@@ -1820,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
@@ -1851,25 +1850,22 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       Type t = type;
-                       ILGenerator ig = ec.ig;
-                       
                        base.Emit (ec);
-#if GMCS_SOURCE
-                       if (t.IsGenericParameter || t.IsGenericType && t.IsValueType)
-                               ig.Emit (OpCodes.Unbox_Any, t);
-                       else
-#endif
-                       {
-                               ig.Emit (OpCodes.Unbox, t);
 
-                               LoadFromPtr (ig, t);
-                       }
+                       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)
                {
                        type = storey.MutateType (type);
+                       base.MutateHoistedGenericType (storey);                 
                }
        }
        
@@ -2121,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);
                }
        }
 
@@ -2170,23 +2158,22 @@ namespace Mono.CSharp {
        //
        public class ReducedExpression : Expression
        {
-               class ReducedConstantExpression : Constant
+               sealed class ReducedConstantExpression : EmptyConstantCast
                {
-                       readonly Constant expr;
                        readonly Expression orig_expr;
 
                        public ReducedConstantExpression (Constant expr, Expression orig_expr)
-                               : base (expr.Location)
+                               : base (expr, expr.Type)
                        {
-                               this.expr = expr;
                                this.orig_expr = orig_expr;
-                               eclass = expr.eclass;
-                               type = expr.Type;
                        }
 
-                       public override string AsString ()
+                       public override Constant ConvertImplicitly (Type target_type)
                        {
-                               return expr.AsString ();
+                               Constant c = base.ConvertImplicitly (target_type);
+                               if (c != null)
+                                       c = new ReducedConstantExpression (c, orig_expr);
+                               return c;
                        }
 
                        public override Expression CreateExpressionTree (EmitContext ec)
@@ -2200,51 +2187,57 @@ namespace Mono.CSharp {
                                // Even if resolved result is a constant original expression was not
                                // and attribute accepts constants only
                                //
-                               Attribute.Error_AttributeArgumentNotValid (loc);
+                               Attribute.Error_AttributeArgumentNotValid (orig_expr.Location);
                                value = null;
                                return false;
                        }
 
-                       public override object GetValue ()
-                       {
-                               return expr.GetValue ();
-                       }
-
                        public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
                        {
-                               throw new NotImplementedException ();
+                               Constant c = base.ConvertExplicitly (in_checked_context, target_type);
+                               if (c != null)
+                                       c = new ReducedConstantExpression (c, orig_expr);
+                               return c;
                        }
+               }
 
-                       public override Expression DoResolve (EmitContext ec)
+               sealed class ReducedExpressionStatement : ExpressionStatement
+               {
+                       readonly Expression orig_expr;
+                       readonly ExpressionStatement stm;
+
+                       public ReducedExpressionStatement (ExpressionStatement stm, Expression orig)
                        {
-                               return this;
+                               this.orig_expr = orig;
+                               this.stm = stm;
+                               this.loc = orig.Location;
                        }
 
-                       public override Constant Increment ()
+                       public override Expression CreateExpressionTree (EmitContext ec)
                        {
-                               throw new NotImplementedException ();
+                               return orig_expr.CreateExpressionTree (ec);
                        }
 
-                       public override bool IsDefaultValue {
-                               get {
-                                       return expr.IsDefaultValue;
-                               }
+                       public override Expression DoResolve (EmitContext ec)
+                       {
+                               eclass = stm.eclass;
+                               type = stm.Type;
+                               return this;
                        }
 
-                       public override bool IsNegative {
-                               get {
-                                       return expr.IsNegative;
-                               }
+                       public override void Emit (EmitContext ec)
+                       {
+                               stm.Emit (ec);
                        }
 
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+                       public override void EmitStatement (EmitContext ec)
                        {
-                               expr.MutateHoistedGenericType (storey);
+                               stm.EmitStatement (ec);
                        }
 
-                       public override void Emit (EmitContext ec)
+                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                        {
-                               expr.Emit (ec);
+                               stm.MutateHoistedGenericType (storey);
                        }
                }
 
@@ -2257,17 +2250,26 @@ namespace Mono.CSharp {
                        this.loc = orig_expr.Location;
                }
 
-               public static Expression Create (Constant expr, Expression original_expr)
+               public static Constant Create (Constant expr, Expression original_expr)
                {
                        return new ReducedConstantExpression (expr, original_expr);
                }
 
+               public static ExpressionStatement Create (ExpressionStatement s, Expression orig)
+               {
+                       return new ReducedExpressionStatement (s, orig);
+               }
+
                public static Expression Create (Expression expr, Expression original_expr)
                {
                        Constant c = expr as Constant;
                        if (c != null)
                                return Create (c, original_expr);
 
+                       ExpressionStatement s = expr as ExpressionStatement;
+                       if (s != null)
+                               return Create (s, original_expr);
+
                        return new ReducedExpression (expr, original_expr);
                }
 
@@ -2326,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) {
@@ -2357,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));
                }
@@ -2402,8 +2416,8 @@ namespace Mono.CSharp {
                                        "A field initializer cannot reference the nonstatic field, method, or property `{0}'",
                                        name);
                        else
-                               Report.Error (
-                                       120, l, "`{0}': An object reference is required for the nonstatic field, method or property",
+                               Report.Error (120, l,
+                                       "An object reference is required to access non-static member `{0}'",
                                        name);
                }
 
@@ -2460,14 +2474,14 @@ 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));
 
                                        if (targs != null)
                                                new_args.Add (targs);
 
-                                       return new ConstructedType (t, new_args, loc);
+                                       return new GenericTypeExpr (t, new_args, loc);
                                }
                        }
 
@@ -2492,7 +2506,7 @@ namespace Mono.CSharp {
                                        return nested.ResolveAsTypeStep (ec, false);
 
                                if (targs != null) {
-                                       ConstructedType ct = new ConstructedType (fne, targs, loc);
+                                       GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
                                        return ct.ResolveAsTypeStep (ec, false);
                                }
 
@@ -2516,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);
@@ -2534,7 +2548,7 @@ namespace Mono.CSharp {
                        if (targs != null) {
                                FullNamedExpression retval = ec.DeclContainer.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
                                if (retval != null) {
-                                       Namespace.Error_TypeArgumentsCannotBeUsed (retval.Type, loc);
+                                       Namespace.Error_TypeArgumentsCannotBeUsed (retval, loc);
                                        return;
                                }
                        }
@@ -2608,16 +2622,9 @@ namespace Mono.CSharp {
                        if (current_block != null){
                                LocalInfo vi = current_block.GetLocalInfo (Name);
                                if (vi != null){
-                                       if (targs != null) {
-                                               Report.Error (307, loc,
-                                                             "The variable `{0}' cannot be used with type arguments",
-                                                             Name);
-                                               return 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)
@@ -2626,25 +2633,11 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               ParameterReference pref = current_block.Toplevel.GetParameterReference (Name, loc);
-                               if (pref != null) {
-                                       if (targs != null) {
-                                               Report.Error (307, loc,
-                                                             "The variable `{0}' cannot be used with type arguments",
-                                                             Name);
-                                               return null;
-                                       }
-
-                                       if (right_side != null)
-                                               return pref.ResolveLValue (ec, right_side, loc);
-                                       else
-                                               return pref.Resolve (ec);
-                               }
-
-                               Expression expr = current_block.Toplevel.GetTransparentIdentifier (Name);
+                               Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
                                if (expr != null) {
                                        if (right_side != null)
-                                               return expr.ResolveLValue (ec, right_side, loc);
+                                               return expr.ResolveLValue (ec, right_side);
+
                                        return expr.Resolve (ec);
                                }
                        }
@@ -2662,14 +2655,20 @@ namespace Mono.CSharp {
 
                                e = MemberLookup (ec.ContainerType, lookup_ds.TypeBuilder, Name, loc);
                                if (e != null) {
-                                       if (e is PropertyExpr) {
+                                       PropertyExpr pe = e as PropertyExpr;
+                                       if (pe != null) {
+                                               AParametersCollection param = TypeManager.GetParameterData (pe.PropertyInfo);
+
                                                // since TypeManager.MemberLookup doesn't know if we're doing a lvalue access or not,
                                                // it doesn't know which accessor to check permissions against
-                                               if (((PropertyExpr) e).IsAccessibleFrom (ec.ContainerType, right_side != null))
+                                               if (param.IsEmpty && pe.IsAccessibleFrom (ec.ContainerType, right_side != null))
                                                        break;
                                        } 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;
                                        }
@@ -2704,22 +2703,18 @@ namespace Mono.CSharp {
                                        }
                                }
 
+                               if (RootContext.EvalMode){
+                                       FieldInfo fi = Evaluator.LookupField (Name);
+                                       if (fi != null)
+                                               return new FieldExpr (fi, loc).Resolve (ec);
+                               }
+
                                if (almost_matched != null)
                                        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;
-
-                               ConstructedType ct = new ConstructedType (
-                                       e.Type, targs, loc);
-                               return ct.ResolveAsTypeStep (ec, false);
                        }
 
                        if (e is MemberExpr) {
@@ -2757,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) &&
@@ -2778,18 +2775,19 @@ namespace Mono.CSharp {
 
                        return e;
                }
-               
-               protected override void CloneTo (CloneContext clonectx, Expression target)
-               {
-                       // CloneTo: Nothing, we do not keep any state on this expression
-               }
        }
 
        /// <summary>
        ///   Represents a namespace or a type.  The name of the class was inspired by
        ///   section 10.8.1 (Fully Qualified Names).
        /// </summary>
-       public abstract class FullNamedExpression : Expression {
+       public abstract class FullNamedExpression : Expression
+       {
+               protected override void CloneTo (CloneContext clonectx, Expression target)
+               {
+                       // Do nothing, most unresolved type expressions cannot be
+                       // resolved to different type
+               }
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
@@ -2817,7 +2815,7 @@ namespace Mono.CSharp {
        ///   Expression that evaluates to a type
        /// </summary>
        public abstract class TypeExpr : FullNamedExpression {
-               override public FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
+               public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
                {
                        TypeExpr t = DoResolveAsTypeStep (ec);
                        if (t == null)
@@ -2837,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 {
@@ -2914,189 +2907,56 @@ 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;
                }
 
-               protected override void CloneTo (CloneContext clonectx, Expression target)
-               {
-                       // CloneTo: Nothing, we do not keep any state on this expression
-               }
-
                public override string GetSignatureForError ()
                {
                        if (type == null)
-                               return TypeManager.CSharpName (name);
+                               return TypeManager.CSharpName (ns_name + "." + name, null);
 
                        return base.GetSignatureForError ();
                }
        }
 
-       /// <summary>
-       ///   Represents an "unbound generic type", ie. typeof (Foo<>).
-       ///   See 14.5.11.
-       /// </summary>
-       public class UnboundTypeExpression : TypeExpr
-       {
-               MemberName name;
-
-               public UnboundTypeExpression (MemberName name, Location l)
-               {
-                       this.name = name;
-                       loc = l;
-               }
-
-               protected override void CloneTo (CloneContext clonectx, Expression target)
-               {
-                       // Nothing to clone
-               }
-
-               protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
-               {
-                       Expression expr;
-                       if (name.Left != null) {
-                               Expression lexpr = name.Left.GetTypeExpression ();
-                               expr = new MemberAccess (lexpr, name.Basename);
-                       } else {
-                               expr = new SimpleName (name.Basename, loc);
-                       }
-
-                       FullNamedExpression fne = expr.ResolveAsTypeStep (ec, false);
-                       if (fne == null)
-                               return null;
-
-                       type = fne.Type;
-                       return new TypeExpression (type, loc);
-               }
-       }
-
        /// <summary>
        ///   This class denotes an expression which evaluates to a member
        ///   of a struct or a class.
@@ -3175,10 +3035,22 @@ namespace Mono.CSharp {
                        //
 
                        if (left is TypeExpr) {
-                               left = left.ResolveAsTypeTerminal (ec, true);
+                               left = left.ResolveAsBaseTerminal (ec, false);
                                if (left == null)
                                        return null;
 
+                               // TODO: Same problem as in class.cs, TypeTerminal does not
+                               // always do all necessary checks
+                               ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (left.Type);
+                               if (oa != null && !ec.IsInObsoleteScope) {
+                                       AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc);
+                               }
+
+                               GenericTypeExpr ct = left as GenericTypeExpr;
+                               if (ct != null && !ct.CheckConstraints (ec))
+                                       return null;
+                               //
+
                                if (!IsStatic) {
                                        SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
                                        return null;
@@ -3213,8 +3085,8 @@ namespace Mono.CSharp {
                                SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
                                return;
                        }
-                               
-                       if (InstanceExpression.Type.IsValueType) {
+
+                       if (TypeManager.IsValueType (InstanceExpression.Type)) {
                                if (InstanceExpression is IMemoryLocation) {
                                        ((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.LoadStore);
                                } else {
@@ -3261,39 +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)
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       if (arguments == null)
-                               arguments = new ArrayList (1);
-                       arguments.Insert (0, extension_argument);
-                       base.EmitCall (ec, arguments);
+                       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);
@@ -3310,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);
                }               
        }
 
@@ -3322,6 +3185,7 @@ namespace Mono.CSharp {
        {
                public interface IErrorHandler
                {
+                       bool AmbiguousCall (MethodBase ambiguous);
                        bool NoExactMatch (EmitContext ec, MethodBase method);
                }
 
@@ -3331,7 +3195,9 @@ namespace Mono.CSharp {
                // TODO: make private
                public TypeArguments type_arguments;
                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)
@@ -3340,6 +3206,12 @@ namespace Mono.CSharp {
                        mi.CopyTo (Methods, 0);
                }
 
+               public MethodGroupExpr (MemberInfo[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
+                       : this (mi, type, l)
+               {
+                       has_inaccessible_candidates_only = inacessibleCandidatesOnly;
+               }
+
                public MethodGroupExpr (ArrayList list, Type type, Location l)
                        : this (type, l)
                {
@@ -3362,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;
                        }
                }
 
@@ -3385,10 +3254,6 @@ namespace Mono.CSharp {
                        get {
                                return identical_type_name;
                        }
-
-                       set {
-                               identical_type_name = value;
-                       }
                }
 
                public override string GetSignatureForError ()
@@ -3543,29 +3408,33 @@ 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)
                {
-                       ParameterData candidate_pd = TypeManager.GetParameterData (candidate);
-                       ParameterData best_pd = TypeManager.GetParameterData (best);
+                       AParametersCollection candidate_pd = TypeManager.GetParameterData (candidate);
+                       AParametersCollection best_pd = TypeManager.GetParameterData (best);
                
                        bool better_at_least_one = false;
                        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 = TypeManager.TypeToCoreType (candidate_pd.ParameterType (c_idx));
-                               Type bt = TypeManager.TypeToCoreType (best_pd.ParameterType (b_idx));
+                               Type ct = candidate_pd.Types [c_idx];
+                               Type bt = best_pd.Types [b_idx];
 
-                               if (candidate_params && candidate_pd.ParameterModifier (c_idx) == Parameter.Modifier.PARAMS) 
+                               if (candidate_params && candidate_pd.FixedParameters [c_idx].ModFlags == Parameter.Modifier.PARAMS) 
                                {
                                        ct = TypeManager.GetElementType (ct);
                                        --c_idx;
                                }
 
-                               if (best_params && best_pd.ParameterModifier (b_idx) == Parameter.Modifier.PARAMS) 
+                               if (best_params && best_pd.FixedParameters [b_idx].ModFlags == Parameter.Modifier.PARAMS) 
                                {
                                        bt = TypeManager.GetElementType (bt);
                                        --b_idx;
@@ -3606,10 +3475,12 @@ namespace Mono.CSharp {
                        //
                        // The two methods have equal parameter types.  Now apply tie-breaking rules
                        //
-                       if (TypeManager.IsGenericMethod (best) && !TypeManager.IsGenericMethod (candidate))
-                               return true;
-                       if (!TypeManager.IsGenericMethod (best) && TypeManager.IsGenericMethod (candidate))
+                       if (TypeManager.IsGenericMethod (best)) {
+                               if (!TypeManager.IsGenericMethod (candidate))
+                                       return true;
+                       } else if (TypeManager.IsGenericMethod (candidate)) {
                                return false;
+                       }
 
                        //
                        // This handles the following cases:
@@ -3629,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
@@ -3639,14 +3510,14 @@ namespace Mono.CSharp {
                        MethodBase orig_candidate = TypeManager.DropGenericMethodArguments (candidate);
                        MethodBase orig_best = TypeManager.DropGenericMethodArguments (best);
 
-                       ParameterData orig_candidate_pd = TypeManager.GetParameterData (orig_candidate);
-                       ParameterData orig_best_pd = TypeManager.GetParameterData (orig_best);
+                       AParametersCollection orig_candidate_pd = TypeManager.GetParameterData (orig_candidate);
+                       AParametersCollection orig_best_pd = TypeManager.GetParameterData (orig_best);
 
                        bool specific_at_least_once = false;
                        for (int j = 0; j < candidate_param_count; ++j) 
                        {
-                               Type ct = TypeManager.TypeToCoreType (orig_candidate_pd.ParameterType (j));
-                               Type bt = TypeManager.TypeToCoreType (orig_best_pd.ParameterType (j));
+                               Type ct = orig_candidate_pd.Types [j];
+                               Type bt = orig_best_pd.Types [j];
                                if (ct.Equals (bt))
                                        continue;
                                Type specific = MoreSpecific (ct, bt);
@@ -3683,7 +3554,7 @@ namespace Mono.CSharp {
                {
                        if (!(left is TypeExpr) &&
                            original != null && original.IdenticalNameAndTypeName (ec, left, loc))
-                               IdenticalTypeName = true;
+                               identical_type_name = true;
 
                        return base.ResolveMemberAccess (ec, left, loc, original);
                }
@@ -3728,31 +3599,39 @@ 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,
-                                                                                                       Argument a, ParameterData expected_par, Type paramType)
+                                                                                                       Argument a, AParametersCollection expected_par, Type paramType)
                {
                        ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
 
                        if (a is CollectionElementInitializer.ElementInitializerArgument) {
                                Report.SymbolRelatedToPreviousError (method);
-                               if ((expected_par.ParameterModifier (idx) & Parameter.Modifier.ISBYREF) != 0) {
+                               if ((expected_par.FixedParameters [idx].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
                                        Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
                                                TypeManager.CSharpSignature (method));
                                        return;
                                }
                                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,
@@ -3763,11 +3642,9 @@ 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 = expected_par.ParameterModifier (idx);
+                       Parameter.Modifier mod = idx >= expected_par.Count ? 0 : expected_par.FixedParameters [idx].ModFlags;
 
                        string index = (idx + 1).ToString ();
                        if (((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) ^
@@ -3803,8 +3680,14 @@ 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, ParameterData parameters)
+               protected virtual int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
                {
                        return parameters.Count;
                }               
@@ -3823,18 +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;
 
-                       ParameterData pd = TypeManager.GetParameterData (candidate);
+                       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
@@ -3866,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
@@ -3875,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.ParameterModifier (i) & ~(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;
+                               }
 
-                                       pt = pd.ParameterType (i);
+                               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) {
+                               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;
                                }
@@ -3913,7 +3881,7 @@ namespace Mono.CSharp {
                        }
                        
                        if (arg_count != param_count)
-                               params_expanded_form = true;                    
+                               params_expanded_form = true;    
                        
                        return 0;
                }
@@ -3925,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;
                        }
 
@@ -3951,18 +3917,18 @@ namespace Mono.CSharp {
                        if (!IsAncestralType (base_method.DeclaringType, cand_method.DeclaringType))
                                return false;
 
-                       ParameterData cand_pd = TypeManager.GetParameterData (cand_method);
-                       ParameterData base_pd = TypeManager.GetParameterData (base_method);
+                       AParametersCollection cand_pd = TypeManager.GetParameterData (cand_method);
+                       AParametersCollection base_pd = TypeManager.GetParameterData (base_method);
                
                        if (cand_pd.Count != base_pd.Count)
                                return false;
 
                        for (int j = 0; j < cand_pd.Count; ++j) 
                        {
-                               Parameter.Modifier cm = cand_pd.ParameterModifier (j);
-                               Parameter.Modifier bm = base_pd.ParameterModifier (j);
-                               Type ct = TypeManager.TypeToCoreType (cand_pd.ParameterType (j));
-                               Type bt = TypeManager.TypeToCoreType (base_pd.ParameterType (j));
+                               Parameter.Modifier cm = cand_pd.FixedParameters [j].ModFlags;
+                               Parameter.Modifier bm = base_pd.FixedParameters [j].ModFlags;
+                               Type ct = cand_pd.Types [j];
+                               Type bt = base_pd.Types [j];
 
                                if (cm != bm || ct != bt)
                                        return false;
@@ -4063,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;
 
@@ -4080,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)
@@ -4143,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;
@@ -4156,8 +4122,16 @@ 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);
 
-                               if (candidate_rate != 0) {
+                                       candidates_expanded.Add (Methods [i], candidate_args);
+                                       candidate_args = Arguments;
+                               }
+
+                               if (candidate_rate != 0 || has_inaccessible_candidates_only) {
                                        if (msg_recorder != null)
                                                msg_recorder.EndSession ();
                                        continue;
@@ -4207,12 +4181,10 @@ 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;
 
-                                       ParameterData pd = TypeManager.GetParameterData (best_candidate);
+                                       AParametersCollection pd = TypeManager.GetParameterData (best_candidate);
                                        bool cand_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
                                        if (arg_count == pd.Count || pd.HasParams) {
                                                if (TypeManager.IsGenericMethodDefinition (best_candidate)) {
@@ -4223,8 +4195,8 @@ namespace Mono.CSharp {
                                                                        TypeManager.CSharpSignature (best_candidate));
                                                                return null;
                                                        }
-                                                               
-                                                       Type [] g_args = TypeManager.GetGenericArguments (best_candidate);
+
+                                                       Type[] g_args = TypeManager.GetGenericArguments (best_candidate);
                                                        if (type_arguments.Count != g_args.Length) {
                                                                Report.SymbolRelatedToPreviousError (best_candidate);
                                                                Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
@@ -4238,29 +4210,41 @@ namespace Mono.CSharp {
                                                                return null;
                                                        }
                                                }
-                                               
+
+                                               if (has_inaccessible_candidates_only) {
+                                                       if (InstanceExpression != null && type != ec.ContainerType && TypeManager.IsNestedFamilyAccessible (ec.ContainerType, best_candidate.DeclaringType)) {
+                                                               // Although a derived class can access protected members of
+                                                               // its base class it cannot do so through an instance of the
+                                                               // 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, queried_type, ec.ContainerType);
+                                                       } else {
+                                                               Report.SymbolRelatedToPreviousError (best_candidate);
+                                                               ErrorIsInaccesible (loc, GetSignatureForError ());
+                                                       }
+                                               }
+
                                                if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
                                                        return null;
+
+                                               if (has_inaccessible_candidates_only)
+                                                       return null;
+
+                                               throw new InternalErrorException ("VerifyArgumentsCompat didn't find any problem with rejected candidate " + best_candidate);
                                        }
                                }
 
-                               if (almost_matched_members.Count != 0) {
-                                       Error_MemberLookupFailed (ec.ContainerType, type, type, ".ctor",
-                                       null, MemberTypes.Constructor, AllBindingFlags);
-                                       return null;
-                               }
-                               
                                //
                                // 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;
@@ -4322,8 +4306,16 @@ namespace Mono.CSharp {
                        //
 
                        best_candidate = (MethodBase) candidates [0];
-                       if (delegate_type == null)
-                               method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+                       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];
@@ -4333,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;
@@ -4352,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)) 
                                {
@@ -4363,10 +4355,7 @@ namespace Mono.CSharp {
                        }
 
                        if (ambiguous != null) {
-                               Report.SymbolRelatedToPreviousError (ambiguous);
-                               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;
                        }
 
@@ -4416,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;
 
@@ -4424,16 +4413,22 @@ 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
+                       //
+                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (the_method);
+                       if (oa != null && !ec.IsInObsoleteScope)
+                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
 
                        IMethodData data = TypeManager.GetMethod (the_method);
                        if (data != null)
                                data.SetMemberIsUsed ();
 
+                       Arguments = candidate_args;
                        return this;
                }
                
@@ -4442,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)
                {
-                       ParameterData pd = TypeManager.GetParameterData (method);
+                       AParametersCollection pd = TypeManager.GetParameterData (method);
+                       int param_count = GetApplicableParametersCount (method, pd);
 
                        int errors = Report.Errors;
                        Parameter.Modifier p_mod = 0;
@@ -4458,25 +4454,17 @@ 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.ParameterModifier (a_idx);
-                                       pt = pd.ParameterType (a_idx);
+                                       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);
                                                        pt = TypeManager.GetElementType (pt);
                                                }
-                                       } else if (p_mod != 0) {
-                                               pt = TypeManager.GetElementType (pt);
                                        }
                                }
 
@@ -4491,17 +4479,42 @@ namespace Mono.CSharp {
                                                break;
 
                                        continue;
-                               }
-
-                               Expression conv;
-                               if (TypeManager.IsEqual (a.Type, pt)) {
-                                       conv = a.Expr;
                                } else {
-                                       conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc);
-                                       if (conv == null)
-                                               break;
+                                       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;
+
                                //
                                // Convert params arguments to an array initializer
                                //
@@ -4518,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;
                }
        }
 
@@ -4643,18 +4663,15 @@ namespace Mono.CSharp {
                
                LocalTemporary temp;
                bool prepared;
-               bool in_initializer;
-
-               public FieldExpr (FieldInfo fi, Location l, bool in_initializer):
-                       this (fi, l)
+               
+               protected FieldExpr (Location l)
                {
-                       this.in_initializer = in_initializer;
+                       loc = l;
                }
                
                public FieldExpr (FieldInfo fi, Location l)
                {
                        FieldInfo = fi;
-                       eclass = ExprClass.Variable;
                        type = TypeManager.TypeToCoreType (fi.FieldType);
                        loc = l;
                }
@@ -4662,6 +4679,8 @@ namespace Mono.CSharp {
                public FieldExpr (FieldInfo fi, Type genericType, Location l)
                        : this (fi, l)
                {
+                       if (TypeManager.IsGenericTypeDefinition (genericType))
+                               return;
                        this.constructed_generic_type = genericType;
                }
 
@@ -4729,15 +4748,16 @@ 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);
                }
 
                public Expression CreateTypeOfExpression ()
                {
-                       return new TypeOfField (FieldInfo, loc);
+                       return new TypeOfField (GetConstructedFieldInfo (), loc);
                }
 
                override public Expression DoResolve (EmitContext ec)
@@ -4765,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)
@@ -4780,16 +4804,16 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (!in_initializer && !ec.IsInFieldInitializer) {
-                               ObsoleteAttribute oa;
+                       // TODO: the code above uses some non-standard multi-resolve rules
+                       if (eclass != ExprClass.Invalid)
+                               return this;
+
+                       if (!ec.IsInObsoleteScope) {
                                FieldBase f = TypeManager.GetField (FieldInfo);
                                if (f != null) {
-                                       if (!ec.IsInObsoleteScope)
-                                               f.CheckObsoleteness (loc);
-                                
-                                       // To be sure that type is external because we do not register generated fields
-                               } else if (!(FieldInfo.DeclaringType is TypeBuilder)) {                                
-                                       oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
+                                       f.CheckObsoleteness (loc);
+                               } else {
+                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
                                        if (oa != null)
                                                AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
                                }
@@ -4799,7 +4823,8 @@ namespace Mono.CSharp {
                        IVariableReference var = InstanceExpression as IVariableReference;
                        
                        if (fb != null) {
-                               if (!ec.InFixedInitializer && ec.ContainerType.IsValueType) {
+                               IFixedExpression fe = InstanceExpression as IFixedExpression;
+                               if (!ec.InFixedInitializer && (fe == null || !fe.IsFixed)) {
                                        Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
                                }
 
@@ -4814,6 +4839,8 @@ namespace Mono.CSharp {
                                return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec);
                        }
 
+                       eclass = ExprClass.Variable;
+
                        // If the instance expression is a local variable or parameter.
                        if (var == null || var.VariableInfo == null)
                                return this;
@@ -4823,6 +4850,7 @@ namespace Mono.CSharp {
                                return null;
 
                        variable_info = vi.GetSubStruct (FieldInfo.Name);
+                       eclass = ExprClass.Variable;
                        return this;
                }
 
@@ -4869,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);
@@ -4911,12 +4939,13 @@ namespace Mono.CSharp {
                                                GetSignatureForError ());
                        }
 
+                       eclass = ExprClass.Variable;
                        return this;
                }
 
                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)
@@ -4933,13 +4962,17 @@ namespace Mono.CSharp {
                        return FieldInfo.GetHashCode ();
                }
                
-               public bool IsFixedVariable {
+               public bool IsFixed {
                        get {
                                //
                                // 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.IsFixedVariable;
+                               if (variable != null)
+                                       return TypeManager.IsStruct (InstanceExpression.Type) && variable.IsFixed;
+
+                               IFixedExpression fe = InstanceExpression as IFixedExpression;
+                               return fe != null && fe.IsFixed;
                        }
                }
 
@@ -4987,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 ());
+                                       }
                                }
                        }
 
@@ -5023,7 +5062,7 @@ namespace Mono.CSharp {
                        prepared = prepare_for_load;
                        EmitInstance (ec, prepared);
 
-                       source.Emit (ec);                       
+                       source.Emit (ec);
                        if (leave_copy) {
                                ec.ig.Emit (OpCodes.Dup);
                                if (!FieldInfo.IsStatic) {
@@ -5194,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);
                        }
@@ -5206,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
@@ -5299,7 +5338,10 @@ namespace Mono.CSharp {
                                InstanceExpression.MutateHoistedGenericType (storey);
 
                        type = storey.MutateType (type);
-                       getter = storey.MutateGenericMethod (getter);
+                       if (getter != null)
+                               getter = storey.MutateGenericMethod (getter);
+                       if (setter != null)
+                               setter = storey.MutateGenericMethod (setter);
                }
 
                bool InstanceResolve (EmitContext ec, bool lvalue_instance, bool must_do_cs1540_check)
@@ -5316,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;
@@ -5345,7 +5387,7 @@ namespace Mono.CSharp {
                        
                        StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
                        sig.Append ('.');
-                       ParameterData iparams = TypeManager.GetParameterData (mi);
+                       AParametersCollection iparams = TypeManager.GetParameterData (mi);
                        sig.Append (getter ? "get_" : "set_");
                        sig.Append (Name);
                        sig.Append (iparams.GetSignatureForError ());
@@ -5427,12 +5469,21 @@ namespace Mono.CSharp {
                        //
                        if (IsBase && getter.IsAbstract) {
                                Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
-                               return null;
                        }
 
                        if (PropertyInfo.PropertyType.IsPointer && !ec.InUnsafe){
                                UnsafeError (loc);
-                               return null;
+                       }
+
+                       if (!ec.IsInObsoleteScope) {
+                               PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+                               if (pb != null) {
+                                       pb.CheckObsoleteness (loc);
+                               } else {
+                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+                                       if (oa != null)
+                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+                               }
                        }
 
                        resolved = true;
@@ -5443,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 {
@@ -5467,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 {
@@ -5497,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;
                        
                        //
@@ -5505,13 +5556,23 @@ namespace Mono.CSharp {
                        //
                        if (IsBase && setter.IsAbstract){
                                Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
-                               return null;
                        }
 
                        if (PropertyInfo.PropertyType.IsPointer && !ec.InUnsafe) {
                                UnsafeError (loc);
                        }
 
+                       if (!ec.IsInObsoleteScope) {
+                               PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+                               if (pb != null) {
+                                       pb.CheckObsoleteness (loc);
+                               } else {
+                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+                                       if (oa != null)
+                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+                               }
+                       }
+
                        return this;
                }
                
@@ -5569,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);
                        
@@ -5657,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;
                                
@@ -5746,6 +5807,17 @@ namespace Mono.CSharp {
                                Error_CannotAssign ();
                                return null;
                        }
+
+                       if (!ec.IsInObsoleteScope) {
+                               EventField ev = TypeManager.GetEventField (EventInfo);
+                               if (ev != null) {
+                                       ev.CheckObsoleteness (loc);
+                               } else {
+                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (EventInfo);
+                                       if (oa != null)
+                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+                               }
+                       }
                        
                        return this;
                }               
@@ -5769,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);
                }
        }
@@ -5828,11 +5900,12 @@ 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 IsFixedVariable {
+               public override bool IsFixed {
                        get { return true; }
                }