* mb-parser.jay: Removed 'static_constructor_declaration' - this is not required...
[mono.git] / mcs / mbas / expression.cs
index f19068bd8c288be45d1a9d2477a779d3645d9c91..e59f8f8c26e9e5fb0016e063f43e1ace6dda5e65 100644 (file)
@@ -9,7 +9,7 @@
 //
 #define USE_OLD
 
-namespace Mono.CSharp {
+namespace Mono.MonoBASIC {
        using System;
        using System.Collections;
        using System.Reflection;
@@ -142,8 +142,8 @@ namespace Mono.CSharp {
                {
                        Error (
                                23, "Operator " + OperName (Oper) +
-                               " cannot be applied to operand of type `" +
-                               TypeManager.CSharpName (t) + "'");
+                               " cannot be applied to operand of type '" +
+                               TypeManager.MonoBASIC_Name (t) + "'");
                }
 
                /// <remarks>
@@ -189,7 +189,7 @@ namespace Mono.CSharp {
 
                // <summary>
                //   This routine will attempt to simplify the unary expression when the
-               //   argument is a constant.  The result is returned in `result' and the
+               //   argument is a constant.  The result is returned in 'result' and the
                //   function returns true or false depending on whether a reduction
                //   was performed or not
                // </summary>
@@ -445,7 +445,7 @@ namespace Mono.CSharp {
 
                                if (expr_type == TypeManager.uint64_type){
                                        //
-                                       // FIXME: Handle exception of `long value'
+                                       // FIXME: Handle exception of 'long value'
                                        // -92233720368547758087 (-2^63) to be wrote as
                                        // decimal integer literal.
                                        //
@@ -484,7 +484,7 @@ namespace Mono.CSharp {
                        }
 
                        Error (187, "No such operator '" + OperName (Oper) + "' defined for type '" +
-                              TypeManager.CSharpName (expr_type) + "'");
+                              TypeManager.MonoBASIC_Name (expr_type) + "'");
                        return null;
                }
 
@@ -538,7 +538,7 @@ namespace Mono.CSharp {
                }
 
                /// <summary>
-               ///   This will emit the child expression for `ec' avoiding the logical
+               ///   This will emit the child expression for 'ec' avoiding the logical
                ///   not.  The parent will take care of changing brfalse/brtrue
                /// </summary>
                public void EmitLogicalNot (EmitContext ec)
@@ -658,7 +658,7 @@ namespace Mono.CSharp {
        /// classes (indexers require temporary access;  overloaded require method)
        ///
        /// Maybe we should have classes PreIncrement, PostIncrement, PreDecrement,
-       /// PostDecrement, that way we could save the `Mode' byte as well.  
+       /// PostDecrement, that way we could save the 'Mode' byte as well.  
        /// </remarks>
        public class UnaryMutator : ExpressionStatement {
                public enum Mode : byte {
@@ -691,12 +691,12 @@ namespace Mono.CSharp {
                {
                        Error (
                                23, "Operator " + OperName (mode) + 
-                               " cannot be applied to operand of type `" +
-                               TypeManager.CSharpName (t) + "'");
+                               " cannot be applied to operand of type '" +
+                               TypeManager.MonoBASIC_Name (t) + "'");
                }
 
                /// <summary>
-               ///   Returns whether an object of type `t' can be incremented
+               ///   Returns whether an object of type 't' can be incremented
                ///   or decremented with add/sub (ie, basically whether we can
                ///   use pre-post incr-decr operations on it, but it is not a
                ///   System.Decimal, which we require operator overloading to catch)
@@ -781,7 +781,7 @@ namespace Mono.CSharp {
                        }
 
                        Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
-                              TypeManager.CSharpName (expr_type) + "'");
+                              TypeManager.MonoBASIC_Name (expr_type) + "'");
                        return null;
                }
 
@@ -948,11 +948,11 @@ namespace Mono.CSharp {
        }
 
        /// <summary>
-       ///   Base class for the `Is' and `As' classes. 
+       ///   Base class for the 'Is' and 'As' classes. 
        /// </summary>
        ///
        /// <remarks>
-       ///   FIXME: Split this in two, and we get to save the `Operator' Oper
+       ///   FIXME: Split this in two, and we get to save the 'Operator' Oper
        ///   size. 
        /// </remarks>
        public abstract class Probe : Expression {
@@ -987,7 +987,7 @@ namespace Mono.CSharp {
        }
 
        /// <summary>
-       ///   Implementation of the `is' operator.
+       ///   Implementation of the 'is' operator.
        /// </summary>
        public class Is : Probe {
                public Is (Expression expr, Expression probe_type, Location l)
@@ -1018,7 +1018,7 @@ namespace Mono.CSharp {
                                IntConstant.EmitInt (ig, 1);
                                return;
                        case Action.LeaveOnStack:
-                               // the `e != null' rule.
+                               // the 'e != null' rule.
                                return;
                        case Action.Probe:
                                ig.Emit (OpCodes.Isinst, probe_type);
@@ -1073,14 +1073,14 @@ namespace Mono.CSharp {
                                if (warning_always_matches)
                                        Warning (
                                                183,
-                                               "The expression is always of type `" +
-                                               TypeManager.CSharpName (probe_type) + "'");
+                                               "The expression is always of type '" +
+                                               TypeManager.MonoBASIC_Name (probe_type) + "'");
                                else if (warning_never_matches){
                                        if (!(probe_type.IsInterface || expr.Type.IsInterface))
                                                Warning (
                                                        184,
-                                                       "The expression is never of type `" +
-                                                       TypeManager.CSharpName (probe_type) + "'");
+                                                       "The expression is never of type '" +
+                                                       TypeManager.MonoBASIC_Name (probe_type) + "'");
                                }
                        }
 
@@ -1089,7 +1089,7 @@ namespace Mono.CSharp {
        }
 
        /// <summary>
-       ///   Implementation of the `as' operator.
+       ///   Implementation of the 'as' operator.
        /// </summary>
        public class As : Probe {
                public As (Expression expr, Expression probe_type, Location l)
@@ -1112,9 +1112,9 @@ namespace Mono.CSharp {
                static void Error_CannotConvertType (Type source, Type target, Location loc)
                {
                        Report.Error (
-                               39, loc, "as operator can not convert from `" +
-                               TypeManager.CSharpName (source) + "' to `" +
-                               TypeManager.CSharpName (target) + "'");
+                               39, loc, "as operator can not convert from '" +
+                               TypeManager.MonoBASIC_Name (source) + "' to '" +
+                               TypeManager.MonoBASIC_Name (target) + "'");
                }
                
                public override Expression DoResolve (EmitContext ec)
@@ -1127,6 +1127,13 @@ namespace Mono.CSharp {
                        type = probe_type;
                        eclass = ExprClass.Value;
                        Type etype = expr.Type;
+
+                       if (TypeManager.IsValueType (probe_type)){
+                               Report.Error (77, loc, "The as operator should be used with a reference type only (" +
+                                             TypeManager.MonoBASIC_Name (probe_type) + " is a value type)");
+                               return null;
+                       
+                       }
                        
                        e = ConvertImplicit (ec, expr, probe_type, loc);
                        if (e != null){
@@ -1205,6 +1212,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is SByteConstant){
                                sbyte v = ((SByteConstant) expr).Value;
@@ -1229,6 +1238,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is ShortConstant){
                                short v = ((ShortConstant) expr).Value;
@@ -1253,6 +1264,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is UShortConstant){
                                ushort v = ((UShortConstant) expr).Value;
@@ -1277,6 +1290,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is IntConstant){
                                int v = ((IntConstant) expr).Value;
@@ -1301,6 +1316,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is UIntConstant){
                                uint v = ((UIntConstant) expr).Value;
@@ -1325,6 +1342,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is LongConstant){
                                long v = ((LongConstant) expr).Value;
@@ -1349,6 +1368,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is ULongConstant){
                                ulong v = ((ULongConstant) expr).Value;
@@ -1373,6 +1394,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is FloatConstant){
                                float v = ((FloatConstant) expr).Value;
@@ -1397,6 +1420,8 @@ namespace Mono.CSharp {
                                        return new DoubleConstant ((double) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
                        if (expr is DoubleConstant){
                                double v = ((DoubleConstant) expr).Value;
@@ -1421,6 +1446,8 @@ namespace Mono.CSharp {
                                        return new FloatConstant ((float) v);
                                if (target_type == TypeManager.char_type)
                                        return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
                        }
 
                        return null;
@@ -1434,20 +1461,13 @@ namespace Mono.CSharp {
 
                        int errors = Report.Errors;
 
-                       target_type = target_type.Resolve (ec, ResolveFlags.Type);
+                       type = ec.DeclSpace.ResolveType (target_type, false, Location);
                        
-                       if (target_type == null){
-                               if (errors == Report.Errors)
-                                       Error (-10, "Can not resolve type");
+                       if (type == null)
                                return null;
-                       }
 
-                       type = target_type.Type;
                        eclass = ExprClass.Value;
                        
-                       if (type == null)
-                               return null;
-
                        if (expr is Constant){
                                Expression e = TryReduce (ec, type);
 
@@ -1619,16 +1639,16 @@ namespace Mono.CSharp {
                        if (expr.Type == target_type)
                                return expr;
 
-                       return ConvertImplicit (ec, expr, target_type, new Location (-1));
+                       return ConvertImplicit (ec, expr, target_type, Location.Null);
                }
 
                public static void Error_OperatorAmbiguous (Location loc, Operator oper, Type l, Type r)
                {
                        Report.Error (
-                               34, loc, "Operator `" + OperName (oper) 
-                               + "' is ambiguous on operands of type `"
-                               + TypeManager.CSharpName (l) + "' "
-                               + "and `" + TypeManager.CSharpName (r)
+                               34, loc, "Operator '" + OperName (oper) 
+                               + "' is ambiguous on operands of type '"
+                               + TypeManager.MonoBASIC_Name (l) + "' "
+                               + "and '" + TypeManager.MonoBASIC_Name (r)
                                + "'");
                }
 
@@ -1720,7 +1740,7 @@ namespace Mono.CSharp {
                                        left = ConvertImplicit (ec, left, TypeManager.int64_type, loc);
                                if (r != TypeManager.int64_type)
                                        right = ConvertImplicit (ec, right, TypeManager.int64_type, loc);
-
+                               
                                type = TypeManager.int64_type;
                        } else if (l == TypeManager.uint32_type || r == TypeManager.uint32_type){
                                //
@@ -1776,36 +1796,26 @@ namespace Mono.CSharp {
                        } else if (l == TypeManager.decimal_type || r == TypeManager.decimal_type){
                                if (l != TypeManager.decimal_type)
                                        left = ConvertImplicit (ec, left, TypeManager.decimal_type, loc);
+
                                if (r != TypeManager.decimal_type)
                                        right = ConvertImplicit (ec, right, TypeManager.decimal_type, loc);
-
                                type = TypeManager.decimal_type;
                        } else {
-                               Expression l_tmp, r_tmp;
+                               left = ForceConversion (ec, left, TypeManager.int32_type);
+                               right = ForceConversion (ec, right, TypeManager.int32_type);
 
-                               l_tmp = ForceConversion (ec, left, TypeManager.int32_type);
-                               if (l_tmp == null)
-                                       return false;
-                               
-                               r_tmp = ForceConversion (ec, right, TypeManager.int32_type);
-                               if (r_tmp == null)
-                                       return false;
-
-                               left = l_tmp;
-                               right = r_tmp;
-                               
                                type = TypeManager.int32_type;
                        }
 
-                       return true;
+                       return (left != null) && (right != null);
                }
 
                static public void Error_OperatorCannotBeApplied (Location loc, string name, Type l, Type r)
                {
                        Report.Error (19, loc,
-                              "Operator " + name + " cannot be applied to operands of type `" +
-                              TypeManager.CSharpName (l) + "' and `" +
-                              TypeManager.CSharpName (r) + "'");
+                              "Operator " + name + " cannot be applied to operands of type '" +
+                              TypeManager.MonoBASIC_Name (l) + "' and '" +
+                              TypeManager.MonoBASIC_Name (r) + "'");
                }
                
                void Error_OperatorCannotBeApplied ()
@@ -1925,6 +1935,10 @@ namespace Mono.CSharp {
                                                method = TypeManager.string_concat_object_object;
                                                right = ConvertImplicit (ec, right,
                                                                         TypeManager.object_type, loc);
+                                               if (right == null){
+                                                       Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
+                                                       return null;
+                                               }
                                        }
                                        type = TypeManager.string_type;
 
@@ -1944,6 +1958,10 @@ namespace Mono.CSharp {
                                        
                                        method = TypeManager.string_concat_object_object;
                                        left = ConvertImplicit (ec, left, TypeManager.object_type, loc);
+                                       if (left == null){
+                                               Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
+                                               return null;
+                                       }
                                        Arguments = new ArrayList ();
                                        Arguments.Add (new Argument (left, Argument.AType.Expression));
                                        Arguments.Add (new Argument (right, Argument.AType.Expression));
@@ -2096,15 +2114,21 @@ namespace Mono.CSharp {
                        if (lie || rie){
                                Expression temp;
 
+                               // U operator - (E e, E f)
+                               if (lie && rie && oper == Operator.Subtraction){
+                                       if (l == r){
+                                               type = TypeManager.EnumToUnderlying (l);
+                                               return this;
+                                       } 
+                                       Error_OperatorCannotBeApplied ();
+                                       return null;
+                               }
+                                       
                                //
                                // operator + (E e, U x)
+                               // operator - (E e, U x)
                                //
-                               if (oper == Operator.Addition){
-                                       if (lie && rie){
-                                               Error_OperatorCannotBeApplied ();
-                                               return null;
-                                       }
-
+                               if (oper == Operator.Addition || oper == Operator.Subtraction){
                                        Type enum_type = lie ? l : r;
                                        Type other_type = lie ? r : l;
                                        Type underlying_type = TypeManager.EnumToUnderlying (enum_type);
@@ -2202,14 +2226,15 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (!DoNumericPromotions (ec, l, r)){
-                               Error_OperatorCannotBeApplied ();
+                       //
+                       // This will leave left or right set to null if there is an error
+                       //
+                       DoNumericPromotions (ec, l, r);
+                       if (left == null || right == null){
+                               Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
                                return null;
                        }
 
-                       if (left == null || right == null)
-                               return null;
-
                        //
                        // reload our cached types if required
                        //
@@ -2277,7 +2302,7 @@ namespace Mono.CSharp {
                ///   context of a conditional bool expression.  This function will return
                ///   false if it is was possible to use EmitBranchable, or true if it was.
                ///
-               ///   The expression's code is generated, and we will generate a branch to `target'
+               ///   The expression's code is generated, and we will generate a branch to 'target'
                ///   if the resulting expression value is equal to isTrue
                /// </remarks>
                public bool EmitBranchable (EmitContext ec, Label target, bool onTrue)
@@ -2585,7 +2610,7 @@ namespace Mono.CSharp {
                bool is_add;
 
                //
-               // We assume that `l' is always a pointer
+               // We assume that 'l' is always a pointer
                //
                public PointerArithmetic (bool is_addition, Expression l, Expression r, Type t,
                                          Location loc)
@@ -2686,6 +2711,9 @@ namespace Mono.CSharp {
                {
                        expr = expr.Resolve (ec);
 
+                       if (expr == null)
+                               return null;
+                       
                        if (expr.Type != TypeManager.bool_type)
                                expr = Expression.ConvertImplicitRequired (
                                        ec, expr, TypeManager.bool_type, loc);
@@ -2693,7 +2721,7 @@ namespace Mono.CSharp {
                        trueExpr = trueExpr.Resolve (ec);
                        falseExpr = falseExpr.Resolve (ec);
 
-                       if (expr == null || trueExpr == null || falseExpr == null)
+                       if (trueExpr == null || falseExpr == null)
                                return null;
 
                        eclass = ExprClass.Value;
@@ -2724,8 +2752,8 @@ namespace Mono.CSharp {
                                        if (ConvertImplicit (ec, falseExpr, true_type, loc) != null){
                                                Error (172,
                                                       "Can not compute type of conditional expression " +
-                                                      "as `" + TypeManager.CSharpName (trueExpr.Type) +
-                                                      "' and `" + TypeManager.CSharpName (falseExpr.Type) +
+                                                      "as '" + TypeManager.MonoBASIC_Name (trueExpr.Type) +
+                                                      "' and '" + TypeManager.MonoBASIC_Name (falseExpr.Type) +
                                                       "' convert implicitly to each other");
                                                return null;
                                        }
@@ -2737,8 +2765,8 @@ namespace Mono.CSharp {
                                } else {
                                        Error (173, "The type of the conditional expression can " +
                                               "not be computed because there is no implicit conversion" +
-                                              " from `" + TypeManager.CSharpName (trueExpr.Type) + "'" +
-                                              " and `" + TypeManager.CSharpName (falseExpr.Type) + "'");
+                                              " from '" + TypeManager.MonoBASIC_Name (trueExpr.Type) + "'" +
+                                              " and '" + TypeManager.MonoBASIC_Name (falseExpr.Type) + "'");
                                        return null;
                                }
                        }
@@ -2761,8 +2789,7 @@ namespace Mono.CSharp {
                        Label false_target = ig.DefineLabel ();
                        Label end_target = ig.DefineLabel ();
 
-                       expr.Emit (ec);
-                       ig.Emit (OpCodes.Brfalse, false_target);
+                       Statement.EmitBoolExpression (ec, expr, false_target, false);
                        trueExpr.Emit (ec);
                        ig.Emit (OpCodes.Br, end_target);
                        ig.MarkLabel (false_target);
@@ -2789,7 +2816,7 @@ namespace Mono.CSharp {
                        eclass = ExprClass.Variable;
                }
 
-               // Setting `is_readonly' to false will allow you to create a writable
+               // Setting 'is_readonly' to false will allow you to create a writable
                // reference to a read-only variable.  This is used by foreach and using.
                public LocalVariableReference (Block block, string name, Location l,
                                               VariableInfo variable_info, bool is_readonly)
@@ -2870,7 +2897,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (is_readonly){
-                               Error (1604, "cannot assign to `" + Name + "' because it is readonly");
+                               Error (1604, "cannot assign to '" + Name + "' because it is readonly");
                                return null;
                        }
                        
@@ -2933,7 +2960,7 @@ namespace Mono.CSharp {
 
                        if (!ec.CurrentBranching.IsParameterAssigned (idx)) {
                                Report.Error (165, loc,
-                                             "Use of unassigned local variable `" + name + "'");
+                                             "Use of unassigned local variable '" + name + "'");
                                return false;
                        }
 
@@ -2950,7 +2977,7 @@ namespace Mono.CSharp {
 
                        if (!ec.CurrentBranching.IsParameterAssigned (idx, field_name)) {
                                Report.Error (170, loc,
-                                             "Use of possibly unassigned field `" + field_name + "'");
+                                             "Use of possibly unassigned field '" + field_name + "'");
                                return false;
                        }
 
@@ -3102,147 +3129,19 @@ namespace Mono.CSharp {
                }
        }
        
-       /// <summary>
-       ///   Used for arguments to New(), Invocation()
-       /// </summary>
-       public class Argument {
-               public enum AType : byte {
-                       Expression,
-                       Ref,
-                       Out
-               };
-
-               public readonly AType ArgType;
-               public Expression Expr;
-               
-               public Argument (Expression expr, AType type)
-               {
-                       this.Expr = expr;
-                       this.ArgType = type;
-               }
-
-               public Type Type {
-                       get {
-                               if (ArgType == AType.Ref || ArgType == AType.Out)
-                                       return TypeManager.LookupType (Expr.Type.ToString () + "&");
-                               else
-                                       return Expr.Type;
-                       }
-               }
-
-               public Parameter.Modifier GetParameterModifier ()
-               {
-                       switch (ArgType) {
-                       case AType.Out:
-                               return Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF;
-
-                       case AType.Ref:
-                               return Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
-
-                       default:
-                               return Parameter.Modifier.NONE;
-                       }
-               }
-
-               public static string FullDesc (Argument a)
-               {
-                       return (a.ArgType == AType.Ref ? "ref " :
-                               (a.ArgType == AType.Out ? "out " : "")) +
-                               TypeManager.CSharpName (a.Expr.Type);
-               }
-
-               public bool ResolveMethodGroup (EmitContext ec, Location loc)
-               {
-                       // FIXME: csc doesn't report any error if you try to use `ref' or
-                       //        `out' in a delegate creation expression.
-                       Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
-                       if (Expr == null)
-                               return false;
-
-                       return true;
-               }
-               
-               public bool Resolve (EmitContext ec, Location loc)
-               {
-                       if (ArgType == AType.Ref) {
-                               Expr = Expr.Resolve (ec);
-                               if (Expr == null)
-                                       return false;
-
-                               Expr = Expr.ResolveLValue (ec, Expr);
-                       } else if (ArgType == AType.Out)
-                               Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
-                       else
-                               Expr = Expr.Resolve (ec);
-
-                       if (Expr == null)
-                               return false;
-
-                       if (ArgType == AType.Expression)
-                               return true;
-
-                       if (Expr.eclass != ExprClass.Variable){
-                               //
-                               // We just probe to match the CSC output
-                               //
-                               if (Expr.eclass == ExprClass.PropertyAccess ||
-                                   Expr.eclass == ExprClass.IndexerAccess){
-                                       Report.Error (
-                                               206, loc,
-                                               "A property or indexer can not be passed as an out or ref " +
-                                               "parameter");
-                               } else {
-                                       Report.Error (
-                                               1510, loc,
-                                               "An lvalue is required as an argument to out or ref");
-                               }
-                               return false;
-                       }
-                               
-                       return true;
-               }
-
-               public void Emit (EmitContext ec)
-               {
-                       //
-                       // Ref and Out parameters need to have their addresses taken.
-                       //
-                       // ParameterReferences might already be references, so we want
-                       // to pass just the value
-                       //
-                       if (ArgType == AType.Ref || ArgType == AType.Out){
-                               AddressOp mode = AddressOp.Store;
-
-                               if (ArgType == AType.Ref)
-                                       mode |= AddressOp.Load;
-                               
-                               if (Expr is ParameterReference){
-                                       ParameterReference pr = (ParameterReference) Expr;
-
-                                       if (pr.is_ref)
-                                               pr.EmitLoad (ec);
-                                       else {
-                                               
-                                               pr.AddressOf (ec, mode);
-                                       }
-                               } else
-                                       ((IMemoryLocation)Expr).AddressOf (ec, mode);
-                       } else
-                               Expr.Emit (ec);
-               }
-       }
-
+       
        /// <summary>
        ///   Invocation of methods or delegates.
        /// </summary>
        public class Invocation : ExpressionStatement {
-               public readonly ArrayList Arguments;
+               public ArrayList Arguments;
 
-               Expression expr;
+               public Expression expr;
                MethodBase method = null;
                bool is_base;
-               
+               bool is_left_hand; // Needed for late bound calls
                static Hashtable method_parameter_cache;
+               static MemberFilter CompareName;
 
                static Invocation ()
                {
@@ -3261,6 +3160,7 @@ namespace Mono.CSharp {
                        this.expr = expr;
                        Arguments = arguments;
                        loc = l;
+                       CompareName = new MemberFilter (compare_name_filter);
                }
 
                public Expression Expr {
@@ -3271,7 +3171,7 @@ namespace Mono.CSharp {
 
                /// <summary>
                ///   Returns the Parameters (a ParameterData interface) for the
-               ///   Method `mb'
+               ///   Method 'mb'
                /// </summary>
                public static ParameterData GetParameterData (MethodBase mb)
                {
@@ -3309,6 +3209,15 @@ namespace Mono.CSharp {
                        if (argument_type == null)
                                throw new Exception ("Expression of type " + a.Expr + " does not resolve its type");
 
+                       //
+                       // This is a special case since csc behaves this way. I can't find
+                       // it anywhere in the spec but oh well ...
+                       //
+                       if (argument_expr is NullLiteral && p == TypeManager.string_type && q == TypeManager.object_type)
+                               return 1;
+                       else if (argument_expr is NullLiteral && p == TypeManager.object_type && q == TypeManager.string_type)
+                               return 0;
+                       
                        if (p == q)
                                return 0;
                        
@@ -3325,7 +3234,7 @@ namespace Mono.CSharp {
                        // An implicit constant expression conversion permits the following
                        // conversions:
                        //
-                       //    * A constant-expression of type `int' can be converted to type
+                       //    * A constant-expression of type 'int' can be converted to type
                        //      sbyte, byute, short, ushort, uint, ulong provided the value of
                        //      of the expression is withing the range of the destination type.
                        //
@@ -3513,9 +3422,9 @@ namespace Mono.CSharp {
                        string ret_type = "";
 
                        if (mb is MethodInfo)
-                               ret_type = TypeManager.CSharpName (((MethodInfo) mb).ReturnType);
+                               ret_type = TypeManager.MonoBASIC_Name (((MethodInfo) mb).ReturnType) + " ";
                        
-                       StringBuilder sb = new StringBuilder (ret_type + " " + mb.Name);
+                       StringBuilder sb = new StringBuilder (ret_type + mb.Name);
                        ParameterData pd = GetParameterData (mb);
 
                        int count = pd.Count;
@@ -3656,60 +3565,184 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               static bool CheckParameterAgainstArgument (EmitContext ec, ParameterData pd, int i, Argument a, Type ptype)
+               {
+                       Parameter.Modifier a_mod = a.GetParameterModifier () &
+                               ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
+                       Parameter.Modifier p_mod = pd.ParameterModifier (i) &
+                               ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
+
+                       if (a_mod == p_mod || (a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
+                               if (a_mod == Parameter.Modifier.NONE)                                   
+                                       if (! (ImplicitConversionExists (ec, a.Expr, ptype) || RuntimeConversionExists (ec, a.Expr, ptype)) )
+                                               return false;
+                               
+                               if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
+                                       Type pt = pd.ParameterType (i);
+                                       
+                                       if (!pt.IsByRef)
+                                               pt = TypeManager.LookupType (pt.FullName + "&");
+
+                                       if (pt != a.Type)
+                                               return false;
+                               }
+                       } else
+                               return false;                                   
+                       return true;                                    
+               }
+               
                /// <summary>
                ///  Determines if the candidate method is applicable (section 14.4.2.1)
                ///  to the given set of arguments
                /// </summary>
-               static bool IsApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate)
+               static bool IsApplicable (EmitContext ec, ref ArrayList arguments, MethodBase candidate)
                {
-                       int arg_count;
-
+                       int arg_count, ps_count, po_count;
+                       Type param_type;
+                       
                        if (arguments == null)
                                arg_count = 0;
                        else
                                arg_count = arguments.Count;
 
                        ParameterData pd = GetParameterData (candidate);
-
-                       int pd_count = pd.Count;
-
-                       if (arg_count != pd.Count)
-                               return false;
+                       Parameters ps = GetFullParameters (candidate);
                        
-                       for (int i = arg_count; i > 0; ) {
-                               i--;
-
-                               Argument a = (Argument) arguments [i];
-
-                               Parameter.Modifier a_mod = a.GetParameterModifier () &
-                                       ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
-                               Parameter.Modifier p_mod = pd.ParameterModifier (i) &
-                                       ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
+                       if (ps == null) {
+                               ps_count = 0;
+                               po_count = 0;
+                       }
+                       else
+                       {
+                               ps_count = ps.CountStandardParams();                    
+                               po_count = ps.CountOptionalParams();
+                       }
+                       int pd_count = pd.Count;
 
-                               if (a_mod == p_mod ||
-                                   (a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
-                                       if (a_mod == Parameter.Modifier.NONE)
-                                               if (!ImplicitConversionExists (ec, a.Expr, pd.ParameterType (i)))
-                                                       return false;
+                       // Validate argument count
+                       if (po_count == 0) {
+                               if (arg_count != pd.Count)
+                                       return false;
+                       }
+                       else
+                       {
+                               if ((arg_count < ps_count) || (arg_count > pd_count))
+                                       return false;   
+                       }       
+                       
+                       if (arg_count > 0) {
+                               for (int i = arg_count; i > 0 ; ) {
+                                       i--;
+
+                                       Argument a = (Argument) arguments [i];
+                                       if (a.ArgType == Argument.AType.NoArg)
+                                       {
+                                               Parameter p = (Parameter) ps.FixedParameters[i];
+                                               a = new Argument (p.ParameterInitializer, Argument.AType.Expression);
+                                               param_type = p.ParameterInitializer.Type;
+                                       }
+                                       else 
+                                       {
+                                               param_type = pd.ParameterType (i);
+                                               if (ps != null) {
+                                                       Parameter p = (Parameter) ps.FixedParameters[i];
+                                                       
+                                                       if ((p.ModFlags & Parameter.Modifier.REF) != 0) 
+                                                       {
+                                                               a = new Argument (a.Expr, Argument.AType.Ref);
+                                                               if (!a.Resolve(ec,Location.Null))
+                                                                       return false;
+                                                       }
+                                               }
+                                       }       
+       
+                                       if (!CheckParameterAgainstArgument (ec, pd, i, a, param_type))
+                                               return (false);
+                               }
+                       }
+                       else
+                       {
+                               // If we have no arguments AND the first parameter is optional
+                               // we must check for a candidate (the loop above wouldn't)      
+                               if (po_count > 0) {
+                                       ArrayList arglist = new ArrayList();
                                        
-                                       if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
-                                               Type pt = pd.ParameterType (i);
+                                       // Since we got so far, there's no need to check if
+                                       // arguments are optional; we simply retrieve
+                                       // parameter default values and build a brand-new 
+                                       // argument list.
+                                       
+                                       for (int i = 0; i < ps.FixedParameters.Length; i++) {
+                                               Parameter p = ps.FixedParameters[i];
+                                               Argument a = new Argument (p.ParameterInitializer, Argument.AType.Expression);
+                                               a.Resolve(ec, Location.Null);
+                                               arglist.Add (a);
+                                       }
+                                       arguments = arglist;
+                                       return true;
+                               }
+                       }
+                       // We've found a candidate, so we exchange the dummy NoArg arguments
+                       // with new arguments containing the default value for that parameter
+                       ArrayList newarglist = new ArrayList();
+                       for (int i = 0; i < arg_count; i++) {
+                               Argument a = (Argument) arguments [i];
+                               Parameter p = null;
 
-                                               if (!pt.IsByRef)
-                                                       pt = TypeManager.LookupType (pt.FullName + "&");
+                               if (ps != null)
+                                       p = (Parameter) ps.FixedParameters[i];
 
-                                               if (pt != a.Type)
-                                                       return false;
+                               if (a.ArgType == Argument.AType.NoArg){
+                                       a = new Argument (p.ParameterInitializer, Argument.AType.Expression);
+                                       a.Resolve(ec, Location.Null);
+                               }               
+                               
+                               if ((p != null) && ((p.ModFlags & Parameter.Modifier.REF) != 0))
+                               {
+                                       a.ArgType = Argument.AType.Ref;
+                                       a.Resolve(ec, Location.Null);
+                               }       
+                               newarglist.Add(a);
+                               int n = pd_count - arg_count;
+                               if (n > 0) 
+                               {
+                                       for (int x = 0; x < n; x++) 
+                                       {
+                                               Parameter op = (Parameter) ps.FixedParameters[x + arg_count];
+                                               Argument b = new Argument (op.ParameterInitializer, Argument.AType.Expression);
+                                               b.Resolve(ec, Location.Null);
+                                               newarglist.Add (b);
                                        }
-                               } else
-                                       return false;
+                               }
                        }
-
+                       arguments = newarglist;
                        return true;
                }
                
-               
+               static bool compare_name_filter (MemberInfo m, object filterCriteria)
+               {
+                       return (m.Name == ((string) filterCriteria));
+               }
 
+               static Parameters GetFullParameters (MethodBase mb)
+               {
+                       TypeContainer tc = TypeManager.LookupTypeContainer (mb.DeclaringType);
+                       InternalParameters ip = TypeManager.LookupParametersByBuilder(mb);
+                       
+                       return (ip != null) ? ip.Parameters : null;
+               }
+               
+               // We need an overload for OverloadResolve because Invocation.DoResolve
+               // must pass Arguments by reference, since a later call to IsApplicable
+               // can change the argument list if optional parameters are defined
+               // in the method declaration
+               public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me,
+                                                         ArrayList Arguments, Location loc)
+               {
+                       ArrayList a = Arguments;
+                       return OverloadResolve (ec, me, ref a, loc);    
+               }
+               
                /// <summary>
                ///   Find the Applicable Function Members (7.4.2.1)
                ///
@@ -3727,14 +3760,13 @@ namespace Mono.CSharp {
                ///
                /// </summary>
                public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me,
-                                                         ArrayList Arguments, Location loc)
+                                                         ref ArrayList Arguments, Location loc)
                {
                        ArrayList afm = new ArrayList ();
                        MethodBase method = null;
                        Type current_type = null;
                        int argument_count;
                        ArrayList candidates = new ArrayList ();
-                       
 
                        foreach (MethodBase candidate in me.Methods){
                                int x;
@@ -3748,7 +3780,7 @@ namespace Mono.CSharp {
                                }
 
                                // Check if candidate is applicable (section 14.4.2.1)
-                               if (!IsApplicable (ec, Arguments, candidate))
+                               if (!IsApplicable (ec, ref Arguments, candidate))
                                        continue;
 
                                candidates.Add (candidate);
@@ -3765,6 +3797,7 @@ namespace Mono.CSharp {
                        else
                                argument_count = Arguments.Count;
                        
+                       
                        //
                        // Now we see if we can find params functions, applicable in their expanded form
                        // since if they were applicable in their normal form, they would have been selected
@@ -3789,8 +3822,25 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (method == null)
+                       if (method == null) {
+                               //
+                               // Okay so we have failed to find anything so we
+                               // return by providing info about the closest match
+                               //
+                               for (int i = 0; i < me.Methods.Length; ++i) {
+
+                                       MethodBase c = (MethodBase) me.Methods [i];
+                                       ParameterData pd = GetParameterData (c);
+
+                                       if (pd.Count != argument_count)
+                                               continue;
+
+                                       VerifyArgumentsCompat (ec, Arguments, argument_count, c, false,
+                                                              null, loc);
+                               }
+                               
                                return null;
+                       }
 
                        //
                        // Now check that there are no ambiguities i.e the selected method
@@ -3807,7 +3857,7 @@ namespace Mono.CSharp {
                                // so we debar the params method.
                                //
                                if (IsParamsMethodApplicable (ec, Arguments, candidate) &&
-                                   IsApplicable (ec, Arguments, method))
+                                   IsApplicable (ec, ref Arguments, method))
                                        continue;
                                        
                                int x = BetterFunction (ec, Arguments, method, candidate,
@@ -3825,7 +3875,6 @@ namespace Mono.CSharp {
                        // And now check if the arguments are all compatible, perform conversions
                        // if necessary etc. and return if everything is all right
                        //
-
                        if (VerifyArgumentsCompat (ec, Arguments, argument_count, method,
                                                   chose_params_expanded, null, loc))
                                return method;
@@ -3834,23 +3883,41 @@ namespace Mono.CSharp {
                }
 
                public static bool VerifyArgumentsCompat (EmitContext ec, ArrayList Arguments,
+                       int argument_count,
+                       MethodBase method, 
+                       bool chose_params_expanded,
+                       Type delegate_type,
+                       Location loc)
+               {
+                       return (VerifyArgumentsCompat (ec, Arguments, argument_count,
+                               method, chose_params_expanded, delegate_type, loc, null));
+               }
+                                                                                 
+               public static bool VerifyArgumentsCompat (EmitContext ec, 
+                                                         ArrayList Arguments,
                                                          int argument_count,
                                                          MethodBase method, 
                                                          bool chose_params_expanded,
                                                          Type delegate_type,
-                                                         Location loc)
+                                                         Location loc,
+                                                         string InvokingProperty)
                {
                        ParameterData pd = GetParameterData (method);
                        int pd_count = pd.Count;
-                       
+
                        for (int j = 0; j < argument_count; j++) {
                                Argument a = (Argument) Arguments [j];
                                Expression a_expr = a.Expr;
-                               Type parameter_type = pd.ParameterType (j);
-
+                               Type parameter_type = pd.ParameterType(j);
+                                       
+                               if (parameter_type == null)
+                               {
+                                       Error_WrongNumArguments(loc, (InvokingProperty == null)?((delegate_type == null)?FullMethodDesc (method):delegate_type.ToString ()):InvokingProperty, argument_count);
+                                       return false;   
+                               }
                                if (pd.ParameterModifier (j) == Parameter.Modifier.PARAMS &&
-                                   chose_params_expanded)
-                                       parameter_type = parameter_type.GetElementType ();
+                               chose_params_expanded)
+                                       parameter_type = TypeManager.TypeToCoreType (parameter_type.GetElementType ());
 
                                if (a.Type != parameter_type){
                                        Expression conv;
@@ -3860,10 +3927,16 @@ namespace Mono.CSharp {
                                        if (conv == null) {
                                                if (!Location.IsNull (loc)) {
                                                        if (delegate_type == null) 
-                                                               Report.Error (1502, loc,
-                                                                      "The best overloaded match for method '" +
-                                                                      FullMethodDesc (method) +
-                                                                      "' has some invalid arguments");
+                                                               if (InvokingProperty == null)
+                                                                       Report.Error (1502, loc,
+                                                                               "The best overloaded match for method '" +
+                                                                               FullMethodDesc (method) +
+                                                                               "' has some invalid arguments");
+                                                               else
+                                                                       Report.Error (1502, loc,
+                                                                               "Property '" +
+                                                                               InvokingProperty +
+                                                                               "' has some invalid arguments");
                                                        else
                                                                Report.Error (1594, loc,
                                                                              "Delegate '" + delegate_type.ToString () +
@@ -3893,9 +3966,6 @@ namespace Mono.CSharp {
                                if (a_mod != p_mod &&
                                    pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS) {
                                        if (!Location.IsNull (loc)) {
-                                               Console.WriteLine ("A:P: " + a.GetParameterModifier ());
-                                               Console.WriteLine ("PP:: " + pd.ParameterModifier (j));
-                                               Console.WriteLine ("PT:  " + parameter_type.IsByRef);
                                                Report.Error (1502, loc,
                                                       "The best overloaded match for method '" + FullMethodDesc (method)+
                                                       "' has some invalid arguments");
@@ -3911,24 +3981,48 @@ namespace Mono.CSharp {
 
                        return true;
                }
-               
+       
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       this.is_left_hand = true;
+                       return DoResolve (ec);
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        //
                        // First, resolve the expression that is used to
                        // trigger the invocation
                        //
+                       Expression expr_to_return = null;
+
                        if (expr is BaseAccess)
                                is_base = true;
 
-                       expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+                       if ((ec.ReturnType != null) && (expr.ToString() == ec.BlockName)) {
+                               ec.InvokingOwnOverload = true;
+                               expr = expr.Resolve (ec, ResolveFlags.MethodGroup);
+                               ec.InvokingOwnOverload = false;
+                       }
+                       else                            
+                       {
+                               ec.InvokingOwnOverload = false;
+                               expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+                       }       
                        if (expr == null)
                                return null;
 
-                       if (!(expr is MethodGroupExpr)) {
+                       if (expr is Invocation) {
+                               // FIXME Calls which return an Array are not resolved (here or in the grammar)
+                               expr = expr.Resolve(ec);
+                       }
+
+                       if (!(expr is MethodGroupExpr)) 
+                       {
                                Type expr_type = expr.Type;
 
-                               if (expr_type != null){
+                               if (expr_type != null)
+                               {
                                        bool IsDelegate = TypeManager.IsDelegateType (expr_type);
                                        if (IsDelegate)
                                                return (new DelegateInvocation (
@@ -3936,48 +4030,137 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (!(expr is MethodGroupExpr)){
-                               expr.Error118 (ResolveFlags.MethodGroup);
-                               return null;
-                       }
-
                        //
                        // Next, evaluate all the expressions in the argument list
                        //
-                       if (Arguments != null){
-                               foreach (Argument a in Arguments){
+                       if (Arguments != null)
+                       {
+                               foreach (Argument a in Arguments)
+                               {
+                                       if ((a.ArgType == Argument.AType.NoArg) && (!(expr is MethodGroupExpr)))
+                                               Report.Error (999, "This item cannot have empty arguments");
+                                       
                                        if (!a.Resolve (ec, loc))
-                                               return null;
+                                               return null;                            
                                }
                        }
+                       
+                       if (expr is MethodGroupExpr) 
+                       {
+                               MethodGroupExpr mg = (MethodGroupExpr) expr;
+                               method = OverloadResolve (ec, mg, ref Arguments, loc);
+
+                               if (method == null)
+                               {
+                                       Error (-6,
+                                               "Could not find any applicable function for this argument list");
+                                       return null;
+                               }
 
-                       MethodGroupExpr mg = (MethodGroupExpr) expr;
-                       method = OverloadResolve (ec, mg, Arguments, loc);
+                               if ((method as MethodInfo) != null) 
+                               {
+                                       MethodInfo mi = method as MethodInfo;
+                                       type = TypeManager.TypeToCoreType (mi.ReturnType);
+                                       if (!mi.IsStatic && !mg.IsExplicitImpl && (mg.InstanceExpression == null))
+                                               SimpleName.Error_ObjectRefRequired (ec, loc, mi.Name);
+                               }
 
-                       if (method == null){
-                               Error (-6,
-                                      "Could not find any applicable function for this argument list");
-                               return null;
+                               if ((method as ConstructorInfo) != null) 
+                               {
+                                       ConstructorInfo ci = method as ConstructorInfo;
+                                       type = TypeManager.void_type;
+                                       if (!ci.IsStatic && !mg.IsExplicitImpl && (mg.InstanceExpression == null))
+                                               SimpleName.Error_ObjectRefRequired (ec, loc, ci.Name);
+                               }
+
+                               if (type.IsPointer)
+                               {
+                                       if (!ec.InUnsafe)
+                                       {
+                                               UnsafeError (loc);
+                                               return null;
+                                       }
+                               }
+                               eclass = ExprClass.Value;
+                               expr_to_return = this;
                        }
 
-                       MethodInfo mi = method as MethodInfo;
-                       if (mi != null) {
-                               type = TypeManager.TypeToCoreType (mi.ReturnType);
-                               if (!mi.IsStatic && !mg.IsExplicitImpl && (mg.InstanceExpression == null))
-                                       SimpleName.Error_ObjectRefRequired (ec, loc, mi.Name);
+                       if (expr is PropertyExpr) 
+                       {
+                               PropertyExpr pe = ((PropertyExpr) expr);
+                               pe.PropertyArgs = (ArrayList) Arguments.Clone();
+                               Arguments.Clear();
+                               Arguments = new ArrayList();
+                               MethodBase mi = pe.PropertyInfo.GetGetMethod(true);
+
+                               if(VerifyArgumentsCompat (ec, pe.PropertyArgs, 
+                                       pe.PropertyArgs.Count, mi, false, null, loc, pe.Name)) 
+                               {
+
+                                       expr_to_return = pe.DoResolve (ec);
+                                       expr_to_return.eclass = ExprClass.PropertyAccess;
+                               }
+                               else
+                               {
+                                       throw new Exception("Error resolving Property Access expression\n" + pe.ToString());
+                               }
                        }
 
-                       if (type.IsPointer){
-                               if (!ec.InUnsafe){
-                                       UnsafeError (loc);
-                                       return null;
+                       if (expr is FieldExpr || expr is LocalVariableReference || expr is ParameterReference) {
+                               if (expr.Type.IsArray) {
+                                       // If we are here, expr must be an ArrayAccess
+                                       ArrayList idxs = new ArrayList();
+                                       foreach (Argument a in Arguments)
+                                       {
+                                               idxs.Add (a.Expr);
+                                       }
+                                       ElementAccess ea = new ElementAccess (expr, idxs, expr.Location);
+                                       ArrayAccess aa = new ArrayAccess (ea, expr.Location);
+                                       expr_to_return = aa.DoResolve(ec);
+                                       expr_to_return.eclass = ExprClass.Variable;
+                               }
+                               else
+                               {
+                                       // We can't resolve now, but we
+                                       // have to try to access the array with a call
+                                       // to LateIndexGet/Set in the runtime
+                                       Expression lig_call_expr;
+
+                                       if (!is_left_hand)
+                                               lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", Location.Null);
+                                       else
+                                               lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexSet", Location.Null);
+                                       Expression obj_type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", Location.Null);
+                                       ArrayList adims = new ArrayList();
+
+                                       ArrayList ainit = new ArrayList();
+                                       foreach (Argument a in Arguments)
+                                               ainit.Add ((Expression) a.Expr);
+
+                                       adims.Add ((Expression) new IntLiteral (Arguments.Count));
+
+                                       Expression oace = new ArrayCreation (obj_type, adims, "", ainit, Location.Null);
+
+                                       ArrayList args = new ArrayList();
+                                       args.Add (new Argument(expr, Argument.AType.Expression));
+                                       args.Add (new Argument(oace, Argument.AType.Expression));
+                                       args.Add (new Argument(NullLiteral.Null, Argument.AType.Expression));
+
+                                       Expression lig_call = new Invocation (lig_call_expr, args, Location.Null);
+                                       expr_to_return = lig_call.Resolve(ec);
+                                       expr_to_return.eclass = ExprClass.Variable;
                                }
                        }
-                       
-                       eclass = ExprClass.Value;
-                       return this;
+
+                       return expr_to_return;
                }
 
+        static void Error_WrongNumArguments (Location loc, String name, int arg_count)
+        {
+            Report.Error (1501, loc, "No overload for method `" + name + "' takes `" +
+                                      arg_count + "' arguments");
+        }
+
                // <summary>
                //   Emits the list of arguments as an array
                // </summary>
@@ -4014,7 +4197,7 @@ namespace Mono.CSharp {
                /// 
                ///   The MethodBase argument might be null if the
                ///   emission of the arguments is known not to contain
-               ///   a `params' field (for example in constructors or other routines
+               ///   a 'params' field (for example in constructors or other routines
                ///   that keep their arguments in this structure)
                /// </summary>
                public static void EmitArguments (EmitContext ec, MethodBase mb, ArrayList arguments)
@@ -4036,7 +4219,6 @@ namespace Mono.CSharp {
                                        IntConstant.EmitInt (ig, 0);
                                        ig.Emit (OpCodes.Newarr, pd.ParameterType (0).GetElementType ());
                                }
-
                                return;
                        }
 
@@ -4072,7 +4254,7 @@ namespace Mono.CSharp {
                }
 
                /// <remarks>
-               ///   is_base tells whether we want to force the use of the `call'
+               ///   is_base tells whether we want to force the use of the 'call'
                ///   opcode instead of using callvirt.  Call is required to call
                ///   a specific method, while callvirt will always use the most
                ///   recent method in the vtable.
@@ -4089,13 +4271,21 @@ namespace Mono.CSharp {
                public static void EmitCall (EmitContext ec, bool is_base,
                                             bool is_static, Expression instance_expr,
                                             MethodBase method, ArrayList Arguments, Location loc)
+               {
+                       EmitCall (ec, is_base, is_static, instance_expr, method, Arguments, null, loc);
+               }
+               
+               public static void EmitCall (EmitContext ec, bool is_base,
+                       bool is_static, Expression instance_expr,
+                       MethodBase method, ArrayList Arguments, ArrayList prop_args, Location loc)
                {
                        ILGenerator ig = ec.ig;
                        bool struct_call = false;
 
                        Type decl_type = method.DeclaringType;
 
-                       if (!RootContext.StdLib) {
+                       if (!RootContext.StdLib) 
+                       {
                                // Replace any calls to the system's System.Array type with calls to
                                // the newly created one.
                                if (method == TypeManager.system_int_array_get_length)
@@ -4115,7 +4305,7 @@ namespace Mono.CSharp {
                        }
 
                        //
-                       // This checks the `ConditionalAttribute' on the method, and the
+                       // This checks the 'ConditionalAttribute' on the method, and the
                        // ObsoleteAttribute
                        //
                        TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (method, loc);
@@ -4124,26 +4314,32 @@ namespace Mono.CSharp {
                        if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
                                return;
                        
-                       if (!is_static){
+                       if (!is_static)
+                       {
                                if (decl_type.IsValueType)
                                        struct_call = true;
                                //
                                // If this is ourselves, push "this"
                                //
-                               if (instance_expr == null){
+                               if (instance_expr == null)
+                               {
                                        ig.Emit (OpCodes.Ldarg_0);
-                               } else {
+                               } 
+                               else 
+                               {
                                        //
                                        // Push the instance expression
                                        //
-                                       if (instance_expr.Type.IsValueType){
+                                       if (instance_expr.Type.IsValueType)
+                                       {
                                                //
                                                // Special case: calls to a function declared in a 
                                                // reference-type with a value-type argument need
                                                // to have their value boxed.  
 
                                                struct_call = true;
-                                               if (decl_type.IsValueType){
+                                               if (decl_type.IsValueType)
+                                               {
                                                        //
                                                        // If the expression implements IMemoryLocation, then
                                                        // we can optimize and use AddressOf on the
@@ -4151,11 +4347,13 @@ namespace Mono.CSharp {
                                                        //
                                                        // If not we have to use some temporary storage for
                                                        // it.
-                                                       if (instance_expr is IMemoryLocation){
+                                                       if (instance_expr is IMemoryLocation)
+                                                       {
                                                                ((IMemoryLocation)instance_expr).
                                                                        AddressOf (ec, AddressOp.LoadStore);
                                                        }
-                                                       else {
+                                                       else 
+                                                       {
                                                                Type t = instance_expr.Type;
                                                                
                                                                instance_expr.Emit (ec);
@@ -4163,23 +4361,43 @@ namespace Mono.CSharp {
                                                                ig.Emit (OpCodes.Stloc, temp);
                                                                ig.Emit (OpCodes.Ldloca, temp);
                                                        }
-                                               } else {
+                                               } 
+                                               else 
+                                               {
                                                        instance_expr.Emit (ec);
                                                        ig.Emit (OpCodes.Box, instance_expr.Type);
                                                } 
-                                       } else
+                                       } 
+                                       else
                                                instance_expr.Emit (ec);
                                }
                        }
+                       
+                       if (prop_args != null && prop_args.Count > 0)
+                       {
+                               if (Arguments == null) 
+                                       Arguments = new ArrayList();
+
+                               for (int i = prop_args.Count-1; i >=0 ; i--) 
+                               {
+                                       Arguments.Insert (0,prop_args[i]);
+                               }
+
+                       }
 
                        EmitArguments (ec, method, Arguments);
 
-                       if (is_static || struct_call || is_base){
-                               if (method is MethodInfo) {
+                       if (is_static || struct_call || is_base)
+                       {
+                               if (method is MethodInfo) 
+                               {
                                        ig.Emit (OpCodes.Call, (MethodInfo) method);
-                               } else
+                               } 
+                               else
                                        ig.Emit (OpCodes.Call, (ConstructorInfo) method);
-                       } else {
+                       } 
+                       else 
+                       {
                                if (method is MethodInfo)
                                        ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
                                else
@@ -4187,6 +4405,17 @@ namespace Mono.CSharp {
                        }
                }
                
+               static void EmitPropertyArgs (EmitContext ec, ArrayList prop_args)
+               {
+                       int top = prop_args.Count;
+
+                       for (int i = 0; i < top; i++)
+                       {
+                               Argument a = (Argument) prop_args [i];
+                               a.Emit (ec);
+                       }
+               }
+
                public override void Emit (EmitContext ec)
                {
                        MethodGroupExpr mg = (MethodGroupExpr) this.expr;
@@ -4277,7 +4506,7 @@ namespace Mono.CSharp {
                        // To enable this, look into:
                        // test-34 and test-89 and self bootstrapping.
                        //
-                       // For instance, we can avoid a copy by using `newobj'
+                       // For instance, we can avoid a copy by using 'newobj'
                        // instead of Call + Push-temp on value types.
 //                     value_target = MyEmptyExpression;
                }
@@ -4296,8 +4525,8 @@ namespace Mono.CSharp {
 
                        if (type.IsInterface || type.IsAbstract){
                                Error (
-                                       144, "It is not possible to create instances of interfaces " +
-                                       "or abstract classes");
+                                       30376, "It is not possible to create instances of Interfaces " +
+                                       "or classes marked as MustInherit");
                                return null;
                        }
                        
@@ -4315,7 +4544,7 @@ namespace Mono.CSharp {
                        Expression ml;
                        ml = MemberLookupFinal (ec, type, ".ctor",
                                                MemberTypes.Constructor,
-                                               AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+                                               AllBindingFlags | BindingFlags.Public, loc);
 
                        if (ml == null)
                                return null;
@@ -4440,7 +4669,7 @@ namespace Mono.CSharp {
 
                //
                // The list of Argument types.
-               // This is used to construct the `newarray' or constructor signature
+               // This is used to construct the 'newarray' or constructor signature
                //
                ArrayList arguments;
 
@@ -4511,7 +4740,7 @@ namespace Mono.CSharp {
                        return new ComposedCast (base_type, sb.ToString (), loc);
                }
 
-               void error178 ()
+               void Error_IncorrectArrayInitializer ()
                {
                        Error (178, "Incorrectly structured array initializer");
                }
@@ -4532,19 +4761,34 @@ namespace Mono.CSharp {
                                int value = (int) ((Constant) a.Expr).GetValue ();
                                
                                if (value != probe.Count) {
-                                       error178 ();
+                                       Error_IncorrectArrayInitializer ();
                                        return false;
                                }
                                
                                bounds [idx] = value;
                        }
-                       
+
+                       int child_bounds = -1;
                        foreach (object o in probe) {
                                if (o is ArrayList) {
+                                       int current_bounds = ((ArrayList) o).Count;
+                                       
+                                       if (child_bounds == -1) 
+                                               child_bounds = current_bounds;
+
+                                       else if (child_bounds != current_bounds){
+                                               Error_IncorrectArrayInitializer ();
+                                               return false;
+                                       }
                                        bool ret = CheckIndices (ec, (ArrayList) o, idx + 1, specified_dims);
                                        if (!ret)
                                                return false;
                                } else {
+                                       if (child_bounds != -1){
+                                               Error_IncorrectArrayInitializer ();
+                                               return false;
+                                       }
+                                       
                                        Expression tmp = (Expression) o;
                                        tmp = tmp.Resolve (ec);
                                        if (tmp == null)
@@ -4630,7 +4874,7 @@ namespace Mono.CSharp {
                                UpdateIndices (ec);
                                
                                if (arguments.Count != dimensions) {
-                                       error178 ();
+                                       Error_IncorrectArrayInitializer ();
                                        return false;
                                }
 
@@ -4644,7 +4888,7 @@ namespace Mono.CSharp {
                }
                
                //
-               // Converts `source' to an int, uint, long or ulong.
+               // Converts 'source' to an int, uint, long or ulong.
                //
                Expression ExpressionToArrayArgument (EmitContext ec, Expression source)
                {
@@ -4698,7 +4942,7 @@ namespace Mono.CSharp {
                        StringBuilder array_qualifier = new StringBuilder (rank);
 
                        //
-                       // `In the first form allocates an array instace of the type that results
+                       // 'In the first form allocates an array instace of the type that results
                        // from deleting each of the individual expression from the expression list'
                        //
                        if (num_arguments > 0) {
@@ -4713,6 +4957,7 @@ namespace Mono.CSharp {
                        //
                        Expression array_type_expr;
                        array_type_expr = new ComposedCast (requested_base_type, array_qualifier.ToString (), loc);
+                       string sss = array_qualifier.ToString ();
                        type = ec.DeclSpace.ResolveType (array_type_expr, false, loc);
 
                        if (type == null)
@@ -4830,9 +5075,12 @@ namespace Mono.CSharp {
                        byte [] element;
                        int count = array_data.Count;
 
+                       if (underlying_type.IsEnum)
+                               underlying_type = TypeManager.EnumToUnderlying (underlying_type);
+                       
                        factor = GetTypeSize (underlying_type);
                        if (factor == 0)
-                               return null;
+                               throw new Exception ("unrecognized type in MakeByteBlob: " + underlying_type);
 
                        data = new byte [(count * factor + 4) & ~3];
                        int idx = 0;
@@ -4936,8 +5184,20 @@ namespace Mono.CSharp {
                                                bool val = (bool) v;
                                                data [idx] = (byte) (val ? 1 : 0);
                                        }
+                               } else if (underlying_type == TypeManager.decimal_type){
+                                       if (!(v is Expression)){
+                                               int [] bits = Decimal.GetBits ((decimal) v);
+                                               int p = idx;
+                                               
+                                               for (int j = 0; j < 4; j++){
+                                                       data [p++] = (byte) (bits [j] & 0xff);
+                                                       data [p++] = (byte) ((bits [j] >> 8) & 0xff);
+                                                       data [p++] = (byte) ((bits [j] >> 16) & 0xff);
+                                                       data [p++] = (byte) (bits [j] >> 24);
+                                               }
+                                       }
                                } else
-                                       throw new Exception ("Unrecognized type in MakeByteBlob");
+                                       throw new Exception ("Unrecognized type in MakeByteBlob: " + underlying_type);
 
                                 idx += factor;
                        }
@@ -4957,16 +5217,14 @@ namespace Mono.CSharp {
                        ILGenerator ig = ec.ig;
                        
                        byte [] data = MakeByteBlob (array_data, underlying_type, loc);
-                       
-                       if (data != null) {
-                               fb = RootContext.MakeStaticData (data);
 
-                               if (is_expression)
-                                       ig.Emit (OpCodes.Dup);
-                               ig.Emit (OpCodes.Ldtoken, fb);
-                               ig.Emit (OpCodes.Call,
-                                        TypeManager.void_initializearray_array_fieldhandle);
-                       }
+                       fb = RootContext.MakeStaticData (data);
+
+                       if (is_expression)
+                               ig.Emit (OpCodes.Dup);
+                       ig.Emit (OpCodes.Ldtoken, fb);
+                       ig.Emit (OpCodes.Call,
+                                TypeManager.void_initializearray_array_fieldhandle);
                }
                
                //
@@ -5023,10 +5281,8 @@ namespace Mono.CSharp {
                                                
                                                ig.Emit (OpCodes.Ldloc, temp);
 
-                                               for (int idx = dims; idx > 0; ) {
-                                                       idx--;
+                                               for (int idx = 0; idx < dims; idx++) 
                                                        IntConstant.EmitInt (ig, current_pos [idx]);
-                                               }
 
                                                //
                                                // If we are dealing with a struct, get the
@@ -5061,7 +5317,7 @@ namespace Mono.CSharp {
                                //
                                // Advance counter
                                //
-                               for (int j = 0; j < dims; j++){
+                               for (int j = dims - 1; j >= 0; j--){
                                        current_pos [j]++;
                                        if (current_pos [j] < (int) bounds [j])
                                                break;
@@ -5132,7 +5388,7 @@ namespace Mono.CSharp {
        }
        
        /// <summary>
-       ///   Represents the `this' construct
+       ///   Represents the 'this' construct
        /// </summary>
        public class This : Expression, IAssignMethod, IMemoryLocation, IVariable {
 
@@ -5203,7 +5459,7 @@ namespace Mono.CSharp {
                                vi.SetAssigned (ec);
                        
                        if (ec.TypeContainer is Class){
-                               Error (1604, "Cannot assign to `this'");
+                               Error (1604, "Cannot assign to 'this'");
                                return null;
                        }
 
@@ -5242,7 +5498,7 @@ namespace Mono.CSharp {
                        //
                        // consider: struct X { int val; int P { set { val = value; }}}
                        //
-                       // Yes, this looks very bad. Look at `NOTAS' for
+                       // Yes, this looks very bad. Look at 'NOTAS' for
                        // an explanation.
                        // ec.ig.Emit (OpCodes.Ldarga_S, (byte) 0);
                }
@@ -5299,10 +5555,21 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       if (!ec.InUnsafe) {
+                               Error (233, "Sizeof may only be used in an unsafe context " +
+                                      "(consider using System.Runtime.InteropServices.Marshal.Sizeof");
+                               return null;
+                       }
+                               
                        type_queried = ec.DeclSpace.ResolveType (QueriedType, false, loc);
                        if (type_queried == null)
                                return null;
 
+                       if (!TypeManager.IsUnmanagedType (type_queried)){
+                               Report.Error (208, "Cannot take the size of an unmanaged type (" + TypeManager.MonoBASIC_Name (type_queried) + ")");
+                               return null;
+                       }
+                       
                        type = TypeManager.int32_type;
                        eclass = ExprClass.Value;
                        return this;
@@ -5342,7 +5609,7 @@ namespace Mono.CSharp {
 
                static void error176 (Location loc, string name)
                {
-                       Report.Error (176, loc, "Static member `" +
+                       Report.Error (176, loc, "Static member '" +
                                      name + "' cannot be accessed " +
                                      "with an instance reference, qualify with a " +
                                      "type name instead");
@@ -5371,13 +5638,13 @@ namespace Mono.CSharp {
                {
                        bool left_is_type, left_is_explicit;
 
-                       // If `left' is null, then we're called from SimpleNameResolve and this is
+                       // If 'left' is null, then we're called from SimpleNameResolve and this is
                        // a member in the currently defining class.
                        if (left == null) {
                                left_is_type = ec.IsStatic || ec.IsFieldInitializer;
                                left_is_explicit = false;
 
-                               // Implicitly default to `this' unless we're static.
+                               // Implicitly default to 'this' unless we're static.
                                if (!ec.IsStatic && !ec.IsFieldInitializer && !ec.InEnumContext)
                                        left = ec.This;
                        } else {
@@ -5412,6 +5679,12 @@ namespace Mono.CSharp {
                                                o = fi.GetValue (fi);
                                        
                                        if (decl_type.IsSubclassOf (TypeManager.enum_type)) {
+                                               if (left_is_explicit && !left_is_type &&
+                                                   !IdenticalNameAndTypeName (ec, left_original, loc)) {
+                                                       error176 (loc, fe.FieldInfo.Name);
+                                                       return null;
+                                               }                                       
+                                               
                                                Expression enum_member = MemberLookup (
                                                        ec, decl_type, "value__", MemberTypes.Field,
                                                        AllBindingFlags, loc); 
@@ -5593,18 +5866,19 @@ namespace Mono.CSharp {
                        }
 
                        if (expr_type.IsPointer){
-                               Error (23, "The `.' operator can not be applied to pointer operands (" +
-                                      TypeManager.CSharpName (expr_type) + ")");
+                               Error (23, "The '.' operator can not be applied to pointer operands (" +
+                                      TypeManager.MonoBASIC_Name (expr_type) + ")");
                                return null;
                        }
 
                        member_lookup = MemberLookup (ec, expr_type, Identifier, loc);
 
-                       if (member_lookup == null){
+                       if (member_lookup == null)
+                       {
                                // Error has already been reported.
                                if (errors < Report.Errors)
                                        return null;
-
+                               
                                //
                                // Try looking the member up from the same type, if we find
                                // it, we know that the error was due to limited visibility
@@ -5612,37 +5886,38 @@ namespace Mono.CSharp {
                                object lookup = TypeManager.MemberLookup (
                                        expr_type, expr_type, AllMemberTypes, AllBindingFlags |
                                        BindingFlags.NonPublic, Identifier);
+                                       
                                if (lookup == null)
-                                       Error (117, "`" + expr_type + "' does not contain a " +
-                                              "definition for `" + Identifier + "'");
-                               else if ((expr_type != ec.ContainerType) &&
-                                        ec.ContainerType.IsSubclassOf (expr_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 expr_type is a parent of the
-                                       // ec.ContainerType and the lookup succeeds with the latter one,
-                                       // then we are in this situation.
-
-                                       lookup = TypeManager.MemberLookup (
-                                               ec.ContainerType, ec.ContainerType, AllMemberTypes,
-                                               AllBindingFlags, Identifier);
-
-                                       if (lookup != null)
-                                               Error (1540, "Cannot access protected member `" +
+                                       Error (30456, "'" + expr_type + "' does not contain a definition for '" + Identifier + "'");
+                               else
+                               {
+                                       if ((expr_type != ec.ContainerType) &&
+                                                ec.ContainerType.IsSubclassOf (expr_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 expr_type is a parent of the
+                                               // ec.ContainerType and the lookup succeeds with the latter one,
+                                               // then we are in this situation.
+
+                                               lookup = TypeManager.MemberLookup(
+                                                                       ec.ContainerType, ec.ContainerType, AllMemberTypes, 
+                                                                       AllBindingFlags, Identifier);
+
+                                               if (lookup != null)
+                                                       Error (1540, "Cannot access protected member '" +
                                                       expr_type + "." + Identifier + "' " +
-                                                      "via a qualifier of type `" +
-                                                      TypeManager.CSharpName (expr_type) + "'; the " +
-                                                      "qualifier must be of type `" +
-                                                      TypeManager.CSharpName (ec.ContainerType) + "' " +
+                                                      "via a qualifier of type '" + TypeManager.MonoBASIC_Name (expr_type) + "'; the " +
+                                                      "qualifier must be of type '" + TypeManager.MonoBASIC_Name (ec.ContainerType) + "' " +
                                                       "(or derived from it)");
-                                       else
-                                               Error (122, "`" + expr_type + "." + Identifier + "' " +
+                                               else
+                                                       Error (30390, "'" + expr_type + "." + Identifier + "' " +
                                                       "is inaccessible because of its protection level");
-                               } else
-                                       Error (122, "`" + expr_type + "." + Identifier + "' " +
+                                       } else
+                                               Error (30390, "'" + expr_type + "." + Identifier + "' " +
                                               "is inaccessible because of its protection level");
-                                             
+                               }  
                                return null;
                        }
 
@@ -5695,6 +5970,8 @@ namespace Mono.CSharp {
                }
        }
 
+       
+       
        /// <summary>
        ///   Implements checked expressions
        /// </summary>
@@ -5719,6 +5996,9 @@ namespace Mono.CSharp {
                        if (Expr == null)
                                return null;
 
+                       if (Expr is Constant)
+                               return Expr;
+                       
                        eclass = Expr.eclass;
                        type = Expr.Type;
                        return this;
@@ -5762,6 +6042,9 @@ namespace Mono.CSharp {
                        if (Expr == null)
                                return null;
 
+                       if (Expr is Constant)
+                               return Expr;
+                       
                        eclass = Expr.eclass;
                        type = Expr.Type;
                        return this;
@@ -5896,7 +6179,7 @@ namespace Mono.CSharp {
                ElementAccess ea;
 
                LocalTemporary [] cached_locations;
-               
+
                public ArrayAccess (ElementAccess ea_data, Location l)
                {
                        ea = ea_data;
@@ -5918,6 +6201,35 @@ namespace Mono.CSharp {
 #endif
 
                        Type t = ea.Expr.Type;
+/*
+                       if (t == typeof (System.Object))
+                       {
+                               // We can't resolve now, but we
+                               // have to try to access the array with a call
+                               // to LateIndexGet in the runtime
+
+                               Expression lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", Location.Null);
+                               Expression obj_type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", Location.Null);
+                               ArrayList adims = new ArrayList();
+
+                               ArrayList ainit = new ArrayList();
+                               foreach (Argument a in ea.Arguments)
+                                       ainit.Add ((Expression) a.Expr);
+
+                               adims.Add ((Expression) new IntLiteral (ea.Arguments.Count));
+
+                               Expression oace = new ArrayCreation (obj_type, adims, "", ainit, Location.Null);
+
+                               ArrayList args = new ArrayList();
+                               args.Add (new Argument(ea.Expr, Argument.AType.Expression));
+                               args.Add (new Argument(oace, Argument.AType.Expression));
+                               args.Add (new Argument(NullLiteral.Null, Argument.AType.Expression));
+
+                               Expression lig_call = new Invocation (lig_call_expr, args, Location.Null);
+                               lig_call = lig_call.Resolve(ec);
+                               return lig_call;
+                       }
+*/
                        if (t.GetArrayRank () != ea.Arguments.Count){
                                ea.Error (22,
                                          "Incorrect number of indexes for array " +
@@ -5957,7 +6269,7 @@ namespace Mono.CSharp {
                }
 
                /// <summary>
-               ///    Emits the right opcode to load an object of Type `t'
+               ///    Emits the right opcode to load an object of Type 't'
                ///    from an array of T
                /// </summary>
                static public void EmitLoadOpcode (ILGenerator ig, Type type)
@@ -5992,12 +6304,14 @@ namespace Mono.CSharp {
                }
 
                /// <summary>
-               ///    Emits the right opcode to store an object of Type `t'
+               ///    Emits the right opcode to store an object of Type 't'
                ///    from an array of T.  
                /// </summary>
                static public void EmitStoreOpcode (ILGenerator ig, Type t)
                {
                        t = TypeManager.TypeToCoreType (t);
+                       if (TypeManager.IsEnumType (t) && t != TypeManager.enum_type)
+                               t = TypeManager.EnumToUnderlying (t);
                        if (t == TypeManager.byte_type || t == TypeManager.sbyte_type ||
                            t == TypeManager.bool_type)
                                ig.Emit (OpCodes.Stelem_I1);
@@ -6013,9 +6327,9 @@ namespace Mono.CSharp {
                                ig.Emit (OpCodes.Stelem_R8);
                        else if (t == TypeManager.intptr_type)
                                ig.Emit (OpCodes.Stelem_I);
-                       else if (t.IsValueType)
+                       else if (t.IsValueType){
                                ig.Emit (OpCodes.Stobj, t);
-                       else
+                       else
                                ig.Emit (OpCodes.Stelem_Ref);
                }
 
@@ -6164,7 +6478,8 @@ namespace Mono.CSharp {
                        // pair
                        //
                        if (rank == 1){
-                               if (t.IsValueType && !TypeManager.IsBuiltinType (t))
+                               if (t == TypeManager.enum_type || t == TypeManager.decimal_type ||
+                                   (t.IsSubclassOf (TypeManager.value_type) && !TypeManager.IsEnumType (t) && !TypeManager.IsBuiltinType (t)))
                                        ig.Emit (OpCodes.Ldelema, t);
                        }
                        
@@ -6286,7 +6601,7 @@ namespace Mono.CSharp {
                        }
 
                        Report.Error (21, loc,
-                                     "Type `" + TypeManager.CSharpName (lookup_type) +
+                                     "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
                                      "' does not have any indexers defined");
                        return null;
                }
@@ -6299,52 +6614,70 @@ namespace Mono.CSharp {
                //
                // Points to our "data" repository
                //
-               ElementAccess ea;
                MethodInfo get, set;
                Indexers ilist;
                ArrayList set_arguments;
+               bool is_base_indexer;
+
+               protected Type indexer_type;
+               protected Type current_type;
+               protected Expression instance_expr;
+               protected ArrayList arguments;
                
-               public IndexerAccess (ElementAccess ea_data, Location l)
+               public IndexerAccess (ElementAccess ea, Location loc)
+                       : this (ea.Expr, false, loc)
                {
-                       ea = ea_data;
-                       eclass = ExprClass.Value;
-                       loc = l;
+                       this.arguments = ea.Arguments;
+               }
+
+               protected IndexerAccess (Expression instance_expr, bool is_base_indexer,
+                                        Location loc)
+               {
+                       this.instance_expr = instance_expr;
+                       this.is_base_indexer = is_base_indexer;
+                       this.eclass = ExprClass.Value;
+                       this.loc = loc;
+               }
+
+               protected virtual bool CommonResolve (EmitContext ec)
+               {
+                       indexer_type = instance_expr.Type;
+                       current_type = ec.ContainerType;
+
+                       return true;
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       Type indexer_type = ea.Expr.Type;
-                       
+                       if (!CommonResolve (ec))
+                               return null;
+
                        //
-                       // Step 1: Query for all `Item' *properties*.  Notice
+                       // Step 1: Query for all 'Item' *properties*.  Notice
                        // that the actual methods are pointed from here.
                        //
                        // This is a group of properties, piles of them.  
 
                        if (ilist == null)
                                ilist = Indexers.GetIndexersForType (
-                                       ec.ContainerType, indexer_type, ea.Location);
-
+                                       current_type, indexer_type, loc);
 
                        //
                        // Step 2: find the proper match
                        //
-                       if (ilist != null && ilist.getters != null && ilist.getters.Count > 0){
-                               Location loc = ea.Location;
-                               
+                       if (ilist != null && ilist.getters != null && ilist.getters.Count > 0)
                                get = (MethodInfo) Invocation.OverloadResolve (
-                                       ec, new MethodGroupExpr (ilist.getters, loc), ea.Arguments, loc);
-                       }
+                                       ec, new MethodGroupExpr (ilist.getters, loc), arguments, loc);
 
                        if (get == null){
-                               ea.Error (154, "indexer can not be used in this context, because " +
-                                         "it lacks a `get' accessor");
+                               Error (154, "indexer can not be used in this context, because " +
+                                      "it lacks a 'get' accessor");
                                return null;
                        }
 
                        type = get.ReturnType;
                        if (type.IsPointer && !ec.InUnsafe){
-                               UnsafeError (ea.Location);
+                               UnsafeError (loc);
                                return null;
                        }
                        
@@ -6354,17 +6687,17 @@ namespace Mono.CSharp {
 
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
-                       Type indexer_type = ea.Expr.Type;
+                       if (!CommonResolve (ec))
+                               return null;
+
                        Type right_type = right_side.Type;
 
                        if (ilist == null)
                                ilist = Indexers.GetIndexersForType (
-                                       ec.ContainerType, indexer_type, ea.Location);
+                                       current_type, indexer_type, loc);
 
                        if (ilist != null && ilist.setters != null && ilist.setters.Count > 0){
-                               Location loc = ea.Location;
-                               
-                               set_arguments = (ArrayList) ea.Arguments.Clone ();
+                               set_arguments = (ArrayList) arguments.Clone ();
                                set_arguments.Add (new Argument (right_side, Argument.AType.Expression));
 
                                set = (MethodInfo) Invocation.OverloadResolve (
@@ -6372,8 +6705,8 @@ namespace Mono.CSharp {
                        }
                        
                        if (set == null){
-                               ea.Error (200, "indexer X.this [" + TypeManager.CSharpName (right_type) +
-                                         "] lacks a `set' accessor");
+                               Error (200, "indexer X.this [" + TypeManager.MonoBASIC_Name (right_type) +
+                                      "] lacks a 'set' accessor");
                                return null;
                        }
 
@@ -6384,7 +6717,7 @@ namespace Mono.CSharp {
                
                public override void Emit (EmitContext ec)
                {
-                       Invocation.EmitCall (ec, false, false, ea.Expr, get, ea.Arguments, ea.Location);
+                       Invocation.EmitCall (ec, false, false, instance_expr, get, arguments, loc);
                }
 
                //
@@ -6394,7 +6727,7 @@ namespace Mono.CSharp {
                //
                public void EmitAssign (EmitContext ec, Expression source)
                {
-                       Invocation.EmitCall (ec, false, false, ea.Expr, set, set_arguments, ea.Location);
+                       Invocation.EmitCall (ec, false, false, instance_expr, set, set_arguments, loc);
                }
        }
 
@@ -6402,7 +6735,7 @@ namespace Mono.CSharp {
        ///   The base operator for method names
        /// </summary>
        public class BaseAccess : Expression {
-               string member;
+               public string member;
                
                public BaseAccess (string member, Location l)
                {
@@ -6418,17 +6751,20 @@ namespace Mono.CSharp {
                        Expression e;
 
                        if (ec.IsStatic){
-                               Error (1511,
-                                             "Keyword base is not allowed in static method");
+                               Error (1511, "Keyword MyBase is not allowed in static method");
                                return null;
                        }
                        
+                       if (member == "New")
+                               member = ".ctor";
+                       
                        member_lookup = MemberLookup (ec, base_type, base_type, member,
                                                      AllMemberTypes, AllBindingFlags, loc);
+
                        if (member_lookup == null) {
-                               Error (117,
-                                             TypeManager.CSharpName (base_type) + " does not " +
-                                             "contain a definition for `" + member + "'");
+                               Error (30456,
+                                             TypeManager.MonoBASIC_Name (base_type) + " does not " +
+                                             "contain a definition for '" + member + "'");
                                return null;
                        }
 
@@ -6459,38 +6795,28 @@ namespace Mono.CSharp {
        /// <summary>
        ///   The base indexer operator
        /// </summary>
-       public class BaseIndexerAccess : Expression {
-               ArrayList Arguments;
-               
-               public BaseIndexerAccess (ArrayList args, Location l)
+       public class BaseIndexerAccess : IndexerAccess {
+               public BaseIndexerAccess (ArrayList args, Location loc)
+                       : base (null, true, loc)
                {
-                       Arguments = args;
-                       loc = l;
+                       arguments = new ArrayList ();
+                       foreach (Expression tmp in args)
+                               arguments.Add (new Argument (tmp, Argument.AType.Expression));
                }
 
-               public override Expression DoResolve (EmitContext ec)
+               protected override bool CommonResolve (EmitContext ec)
                {
-                       Type current_type = ec.ContainerType;
-                       Type base_type = current_type.BaseType;
-                       Expression member_lookup;
+                       instance_expr = ec.This;
 
-                       if (ec.IsStatic){
-                               Error (1511,
-                                             "Keyword base is not allowed in static method");
-                               return null;
-                       }
-                       
-                       member_lookup = MemberLookup (ec, base_type, base_type, "get_Item",
-                                                     MemberTypes.Method, AllBindingFlags, loc);
-                       if (member_lookup == null)
-                               return null;
+                       current_type = ec.ContainerType.BaseType;
+                       indexer_type = current_type;
 
-                       return MemberAccess.ResolveMemberAccess (ec, member_lookup, ec.This, loc, null);
-               }
+                       foreach (Argument a in arguments){
+                               if (!a.Resolve (ec, loc))
+                                       return false;
+                       }
 
-               public override void Emit (EmitContext ec)
-               {
-                       throw new Exception ("Should never be called");
+                       return true;
                }
        }
        
@@ -6502,7 +6828,7 @@ namespace Mono.CSharp {
        ///   we only care about the side effect conversions to be performed
        ///
        ///   This is also now used as a placeholder where a no-action expression
-       ///   is needed (the `New' class).
+       ///   is needed (the 'New' class).
        /// </summary>
        public class EmptyExpression : Expression {
                public EmptyExpression ()
@@ -6594,14 +6920,29 @@ namespace Mono.CSharp {
 
                public Expression DoResolveType (EmitContext ec)
                {
-                       left = left.Resolve (ec, ResolveFlags.Type);
-                       if (left == null)
+                       Type ltype = ec.DeclSpace.ResolveType (left, false, loc);
+                       if (ltype == null)
                                return null;
 
-                       type = RootContext.LookupType (
-                               ec.DeclSpace, left.Type.FullName + dim, false, loc);
-                       if (type == null)
-                               return null;
+                       //
+                       // ltype.Fullname is already fully qualified, so we can skip
+                       // a lot of probes, and go directly to TypeManager.LookupType
+                       //
+                       string cname = ltype.FullName + dim;
+                       type = TypeManager.LookupTypeDirect (cname);
+                       if (type == null){
+                               //
+                               // For arrays of enumerations we are having a problem
+                               // with the direct lookup.  Need to investigate.
+                               //
+                               // For now, fall back to the full lookup in that case.
+                               //
+                               type = RootContext.LookupType (
+                                       ec.DeclSpace, cname, false, loc);
+
+                               if (type == null)
+                                       return null;
+                       }
 
                        if (!ec.ResolvingTypeTree){
                                //
@@ -6712,7 +7053,7 @@ namespace Mono.CSharp {
        }
        
        //
-       // Implements the `stackalloc' keyword
+       // Implements the 'stackalloc' keyword
        //
        public class StackAlloc : Expression {
                Type otype;