fix for different results message
[mono.git] / mcs / mbas / expression.cs
index 93fa0caeffeb1ae27fa2517c7b5eb812f792dd86..8a9c2bbc3c0c49ef297ab18053b8519123f152dd 100644 (file)
@@ -361,6 +361,14 @@ namespace Mono.MonoBASIC {
                                        return this;
                                }
 
+                               if (expr_type == TypeManager.object_type) {
+                                       Expression etmp = Parser.DecomposeQI ("Microsoft.VisualBasic.CompilerServices.ObjectType.NotObj", Location.Null);
+                                       ArrayList arguments = new ArrayList ();
+                                       arguments.Add (new Argument (Expr, Argument.AType.Expression));
+                                       Expression e = new Invocation (etmp, arguments, loc);
+                                       return e.Resolve (ec);
+                               }
+
                                break;
                        case Operator.AddressOf:
                                // Not required in VB ??
@@ -603,9 +611,11 @@ namespace Mono.MonoBASIC {
                        loc = l;
                }
 
+/*
                void LoadExprValue (EmitContext ec)
                {
                }
+*/
                
                public override void Emit (EmitContext ec)
                {
@@ -716,14 +726,6 @@ namespace Mono.MonoBASIC {
                                "++" : "--";
                }
                
-               void Error23 (Type t)
-               {
-                       Error (
-                               30311, "Operator " + OperName (mode) + 
-                               " cannot be applied to operand of type '" +
-                               TypeManager.MonoBASIC_Name (t) + "'");
-               }
-
                /// <summary>
                ///   Returns whether an object of type 't' can be incremented
                ///   or decremented with add/sub (ie, basically whether we can
@@ -1527,137 +1529,6 @@ namespace Mono.MonoBASIC {
                }
        }
 
-        public class Exponentiation : Expression {
-
-               Expression left, right;
-               ArrayList Arguments; 
-               protected MethodBase method;
-       
-               public Exponentiation(Location loc, Expression left, Expression right) {
-                       this.left = left;
-                       this.right = right;
-                       this.loc = loc;
-               }
-
-               public override Expression DoResolve (EmitContext ec)
-               {
-                       left = left.Resolve (ec);
-                       right = right.Resolve (ec);
-
-                       if (left == null || right == null)
-                               return null;
-
-                       if (left.Type == null)
-                               throw new Exception (
-                                       "Resolve returned non null, but did not set the type! (" +
-                                       left + ") at Line: " + loc.Row);
-                       if (right.Type == null)
-                               throw new Exception (
-                                       "Resolve returned non null, but did not set the type! (" +
-                                       right + ") at Line: "+ loc.Row);
-
-                       eclass = ExprClass.Value;
-                       Expression e = null;
-
-                       if (left is EnumConstant) {
-                               left = ((EnumConstant) left).WidenToCompilerConstant();
-                       }
-
-                       if (right is EnumConstant) {
-                               right = ((EnumConstant) right).WidenToCompilerConstant();
-                       }
-
-                       if (left is Constant && right is Constant){
-                               e = ConstantFold.BinaryFold (
-                               ec, Binary.Operator.Exponentiation, (Constant) left, (Constant) right, loc);
-                               if (e != null)
-                                       return e;
-                       }
-                       
-                       Type l = left.Type;
-                       Type r = right.Type;
-
-                       if (left is NullLiteral && right is NullLiteral) {
-                               Error_OperatorCannotBeApplied (loc, "^", l, r);
-                               return null;
-                       }
-                       if (left is NullLiteral)
-                               l = r;
-                       if (right is NullLiteral)
-                               r = l;
-
-                       if (l == TypeManager.object_type || r == TypeManager.object_type) {
-                               if (r.IsValueType)
-                                       right = ConvertImplicit (ec, right, TypeManager.object_type, loc);
-                               if (l.IsValueType)
-                                       left = ConvertImplicit (ec, left, TypeManager.object_type, loc);
-                               if (left == null || right == null) {
-                                       Error_OperatorCannotBeApplied (loc, "^", l, r);
-                                       return null;
-                               }
-
-                               l = left.Type;
-                               r = right.Type;
-
-                               Expression tmp = Mono.MonoBASIC.Parser.DecomposeQI (
-                                                       "Microsoft.VisualBasic.CompilerServices.ObjectType.PowObj",
-                                                       Location.Null);
-
-                               ArrayList arguments = new ArrayList ();
-                               arguments.Add (new Argument (left, Argument.AType.Expression));
-                               arguments.Add (new Argument (right, Argument.AType.Expression));
-                               e = new Invocation (tmp, arguments, loc);
-                               return e.Resolve (ec);
-                       }
-                       
-                       if (l == TypeManager.date_type || r == TypeManager.date_type ||
-                           l == TypeManager.char_type || r == TypeManager.char_type ||
-                           ! l.IsValueType || ! r.IsValueType) {
-                               Error_OperatorCannotBeApplied (loc, "^", l, r);
-                               return null;
-                       }
-
-                       if (l != TypeManager.double_type) { 
-                               left = ConvertImplicit (ec, left, TypeManager.double_type, loc);
-                               if (left == null){
-                                       Error_OperatorCannotBeApplied (loc, "&", l, r);
-                                       return null;
-                               }
-                               type = TypeManager.double_type;
-                       }
-
-                       if (r != TypeManager.double_type) {
-                               right = ConvertImplicit (ec, right, TypeManager.double_type, loc);
-                               if (right == null){
-                                       Error_OperatorCannotBeApplied (loc, "^", l, r);
-                                       return null;
-                               }
-                                        
-                               type = TypeManager.double_type;
-                       }
-
-                        Expression etmp = Mono.MonoBASIC.Parser.DecomposeQI("System.Math.Pow", loc);
-                        ArrayList args = new ArrayList();
-                        args.Add (new Argument (left, Argument.AType.Expression));
-                        args.Add (new Argument (right, Argument.AType.Expression));
-                        e = (Expression) new Invocation (etmp, args, loc);
-                        return e.Resolve(ec);
-               }
-
-                public override void Emit (EmitContext ec)
-                {
-                       throw new Exception ("Should not happen");
-               }
-
-                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.MonoBASIC_Name (l) + "' and '" +
-                               TypeManager.MonoBASIC_Name (r) + "'");
-                }
-
-        }
         public class StringConcat : Expression {
 
                Expression left, right;
@@ -1772,7 +1643,7 @@ namespace Mono.MonoBASIC {
                public enum Operator : byte {
                        Exponentiation,
                        Multiply, Division, IntDivision, Modulus,
-                       Addition, Subtraction,
+                       Addition, Subtraction, Concat,
                        LeftShift, RightShift,
                        LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual, 
                        Equality, Inequality,
@@ -1829,6 +1700,8 @@ namespace Mono.MonoBASIC {
 
                public Binary (Operator oper, Expression left, Expression right, Location loc)
                {
+                       left = Parser.SetValueRequiredFlag (left);
+                       right = Parser.SetValueRequiredFlag (right);
                        this.oper = oper;
                        this.left = left;
                        this.right = right;
@@ -1994,8 +1867,9 @@ namespace Mono.MonoBASIC {
                                else if (r == TypeManager.decimal_type)
                                        conv_right_as = TypeManager.bool_type;
                        } else if ((l == TypeManager.double_type || r == TypeManager.double_type) ||
-                           (oper == Operator.Division && 
-                           !(l == TypeManager.decimal_type || r == TypeManager.decimal_type))) {
+                                  (oper == Operator.Exponentiation) ||
+                                  (oper == Operator.Division && 
+                                  !(l == TypeManager.decimal_type || r == TypeManager.decimal_type))) {
                                //
                                // If either operand is of type double, the other operand is
                                // conveted to type double.
@@ -2158,17 +2032,6 @@ namespace Mono.MonoBASIC {
                                oper == Operator.ExclusiveOr);
                }
 
-               bool IsNumericType (Type type) {
-                       return (type == TypeManager.byte_type ||
-                               type == TypeManager.sbyte_type ||
-                               type == TypeManager.short_type ||
-                               type == TypeManager.int32_type ||
-                               type == TypeManager.int64_type ||
-                               type == TypeManager.decimal_type ||
-                               type == TypeManager.double_type ||
-                               type == TypeManager.float_type);
-               }
-
                Expression ResolveOperator (EmitContext ec)
                {
                        Type l = left.Type;
@@ -2194,18 +2057,21 @@ namespace Mono.MonoBASIC {
                        Type conv_left_as = null;
                        Type conv_right_as = null;
 
-                       if (left is NullLiteral && (r.IsValueType || r == TypeManager.string_type)) {
+                       if ((left is NullLiteral ||(Type.GetTypeCode(l)==TypeCode.DBNull)) && (r.IsValueType || r == TypeManager.string_type)) {
                                // Just treat nothing as the other type, implicit conversion 
                                // will return the default value
                                conv_left_as = r;
                                l = r;
+                               //incase of DBNull set to NullLiteral
+                               left = NullLiteral.Null;
                        }
 
-                       if (right is NullLiteral && (l.IsValueType || l == TypeManager.string_type)) {
+                       if ((right is NullLiteral ||(Type.GetTypeCode(r)==TypeCode.DBNull)) && (l.IsValueType || l == TypeManager.string_type)) {
                                // Just treat nothing as the other type, implicit conversion 
                                // will return the default value
                                conv_right_as = l;
                                r = l;
+                               right = NullLiteral.Null;
                        }
 
                        // deal with objects and reference types first
@@ -2222,9 +2088,11 @@ namespace Mono.MonoBASIC {
                                 // one from the other, then we catch the error there.
 
                                // If other type is a value type, convert it to object
-                               if (l.IsValueType && r == TypeManager.object_type)
+                               if (r == TypeManager.object_type &&
+                                   (l.IsValueType || l == TypeManager.string_type))
                                        left = ConvertImplicit (ec, left, TypeManager.object_type, loc);
-                               if (r.IsValueType && l == TypeManager.object_type)
+                               if (l == TypeManager.object_type &&
+                                   (r.IsValueType || r == TypeManager.string_type))
                                        right = ConvertImplicit (ec, right, TypeManager.object_type, loc);
                                if (left == null || right == null) {
                                        Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
@@ -2478,6 +2346,8 @@ namespace Mono.MonoBASIC {
                                                        conv_left_as = conv_right_as = TypeManager.int64_type;
                                                        type = TypeManager.int64_type;
                                                }
+                                       } else if (oper == Operator.Exponentiation) {
+                                               conv_left_as = conv_right_as = TypeManager.double_type;
                                        } else if (oper == Operator.IntDivision) {
                                                conv_left_as = conv_right_as = TypeManager.int64_type;
                                        } else {
@@ -2590,6 +2460,7 @@ namespace Mono.MonoBASIC {
                                // Required conversions done by 'DoNumericPromotions' method
                                // So Reset 'conv_left_as', 'conv_right_as'
                                conv_left_as = conv_right_as = null;
+
                                if (l == TypeManager.decimal_type  && r == TypeManager.decimal_type) {
                                        if (IsRelationalOperator (oper)) {
                                                Expression etmp = Mono.MonoBASIC.Parser.DecomposeQI ("System.Decimal.Compare", Location.Null);
@@ -2652,6 +2523,16 @@ namespace Mono.MonoBASIC {
                        if (conv_done) 
                                return ResolveOperator (ec);
 
+
+                       if (oper == Operator.Exponentiation) {
+                               Expression etmp = Mono.MonoBASIC.Parser.DecomposeQI("System.Math.Pow", loc);
+                               ArrayList args = new ArrayList();
+                               args.Add (new Argument (left, Argument.AType.Expression));
+                               args.Add (new Argument (right, Argument.AType.Expression));
+                               Expression e = (Expression) new Invocation (etmp, args, loc);
+                               return e.Resolve(ec);
+                       }
+
                        bool overload_failed = false;
                        string op = oper_names [(int) oper];
                        MethodGroupExpr union = null;
@@ -2729,6 +2610,10 @@ namespace Mono.MonoBASIC {
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       if (oper == Operator.Concat) {
+                               Expression e = new StringConcat (loc, left, right);
+                               return e.Resolve (ec);
+                       }
                        left = left.Resolve (ec);
                        right = right.Resolve (ec);
 
@@ -2745,12 +2630,14 @@ namespace Mono.MonoBASIC {
                                        right + ") at Line: "+ loc.Row);
 
                        eclass = ExprClass.Value;
+                       
+                       // To support  'Or' argument of AttributeTargets in AttributeUsage
 
-                       if (left is EnumConstant) {
+                       if (left is EnumConstant && oper != Operator.BitwiseOr) {
                                left = ((EnumConstant) left).WidenToCompilerConstant();
                        }
 
-                       if (right is EnumConstant) {
+                       if (right is EnumConstant && oper != Operator.BitwiseOr) {
                                right = ((EnumConstant) right).WidenToCompilerConstant();
                        }
 
@@ -3421,8 +3308,9 @@ namespace Mono.MonoBASIC {
                {
                        VariableInfo vi = VariableInfo;
 
-                       if (ec.DoFlowAnalysis)
+                       if (ec.DoFlowAnalysis) {
                                ec.SetVariableAssigned (vi);
+                       }
 
                        Expression e = DoResolve (ec);
 
@@ -3442,7 +3330,24 @@ namespace Mono.MonoBASIC {
                        VariableInfo vi = VariableInfo;
                        ILGenerator ig = ec.ig;
 
-                       ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
+                       if (vi.Alias != null && vi.Static) {
+                               ArrayList fields = ec.TypeContainer.Fields;
+                               FieldBase fb = null;
+                               for (int i = 0; i < fields.Count; i++) {
+                                       if (((Field) fields[i]).Name == vi.Alias) {
+                                               fb = (Field) fields[i];
+                                               break;
+                                       }
+                               }
+                               if ((fb.ModFlags & Modifiers.STATIC) != 0)
+                                       ig.Emit (OpCodes.Ldsfld, fb.FieldBuilder);
+                               else {
+                                       ig.Emit (OpCodes.Ldarg_0);              
+                                       ig.Emit (OpCodes.Ldfld, fb.FieldBuilder);
+                               }
+                       } else
+                               ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
+
                        vi.Used = true;
                }
                
@@ -3453,16 +3358,52 @@ namespace Mono.MonoBASIC {
 
                        vi.Assigned = true;
 
-                       source.Emit (ec);
-                       
-                       ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+                       if (vi.Alias != null && vi.Static) {
+                               ArrayList fields = ec.TypeContainer.Fields;
+                               FieldBase fb = null;
+                               for (int i = 0; i < fields.Count; i++) {
+                                       if (((Field) fields[i]).Name == vi.Alias) {
+                                               fb = (Field) fields[i];
+                                               break;
+                                       }
+                               }
+                               if ((fb.ModFlags & Modifiers.STATIC) != 0) {
+                                       source.Emit (ec);
+                                       ig.Emit (OpCodes.Stsfld, fb.FieldBuilder);
+                               }
+                               else {
+                                       ig.Emit (OpCodes.Ldarg_0);
+                                       source.Emit (ec);
+                                       ig.Emit (OpCodes.Stfld, fb.FieldBuilder);
+                               }
+                       }
+                       else {
+                               source.Emit (ec);
+                               ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+                       }
                }
                
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        VariableInfo vi = VariableInfo;
 
-                       ec.ig.Emit (OpCodes.Ldloca, vi.LocalBuilder);
+                       if (vi.Alias != null && vi.Static) {
+                               ArrayList fields = ec.TypeContainer.Fields;
+                               FieldBase fb = null;
+                               for (int i = 0; i < fields.Count; i++) {
+                                       if (((Field) fields[i]).Name == vi.Alias) {
+                                               fb = (Field) fields[i];
+                                               break;
+                                       }
+                               }
+                               if ((fb.ModFlags & Modifiers.STATIC) != 0)
+                                       ec.ig.Emit (OpCodes.Ldsflda, fb.FieldBuilder);
+                               else {
+                                       ec.ig.Emit (OpCodes.Ldarg_0);
+                                       ec.ig.Emit (OpCodes.Ldflda, fb.FieldBuilder);
+                               }
+                       } else
+                               ec.ig.Emit (OpCodes.Ldloca, vi.LocalBuilder);
                }
        }
 
@@ -3545,12 +3486,12 @@ namespace Mono.MonoBASIC {
                {
                        type = pars.GetParameterInfo (ec.DeclSpace, idx, out mod);
                        is_ref = (mod & Parameter.Modifier.ISBYREF) != 0;
-                       is_out = (mod & Parameter.Modifier.OUT) != 0;
+                       // is_out = (mod & Parameter.Modifier.OUT) != 0;
                        eclass = ExprClass.Variable;
 
-                       if (is_out && ec.DoFlowAnalysis && !IsAssigned (ec, loc))
+                       /*  if (is_out && ec.DoFlowAnalysis && !IsAssigned (ec, loc))
                                return null;
-
+                       */
                        return this;
                }
 
@@ -3558,12 +3499,12 @@ namespace Mono.MonoBASIC {
                {
                        type = pars.GetParameterInfo (ec.DeclSpace, idx, out mod);
                        is_ref = (mod & Parameter.Modifier.ISBYREF) != 0;
-                       is_out = (mod & Parameter.Modifier.OUT) != 0;
+                       // is_out = (mod & Parameter.Modifier.OUT) != 0;
                        eclass = ExprClass.Variable;
-
+                       /*
                        if (is_out && ec.DoFlowAnalysis)
                                ec.SetParameterAssigned (idx);
-
+                       */
                        return this;
                }
 
@@ -3672,9 +3613,15 @@ namespace Mono.MonoBASIC {
                public Expression expr;
                MethodBase method = null;
                bool is_base;
+               bool is_latebinding;
                bool is_left_hand; // Needed for late bound calls
+               bool is_retval_required; // Needed for late bound calls
                static Hashtable method_parameter_cache;
-               static MemberFilter CompareName;
+               //static MemberFilter CompareName;
+
+               static ArrayList tempvars; // For ByRef - different parameter and argument type
+               static bool is_byref_conversion = false; //For ByRef when it is converted 
+               static string errorMsg = "";
 
                static Invocation ()
                {
@@ -3691,9 +3638,15 @@ namespace Mono.MonoBASIC {
                public Invocation (Expression expr, ArrayList arguments, Location l)
                {
                        this.expr = expr;
+                       if (this.expr is MemberAccess)
+                               ((MemberAccess) this.expr).IsInvocation = true;
+                       if (this.expr is SimpleName)
+                               ((SimpleName) this.expr).IsInvocation = true;
+                       this.is_retval_required = false;
+                       this.is_left_hand = false;
                        Arguments = arguments;
                        loc = l;
-                       CompareName = new MemberFilter (compare_name_filter);
+                       //CompareName = new MemberFilter (compare_name_filter);
                }
 
                public Expression Expr {
@@ -3702,6 +3655,33 @@ namespace Mono.MonoBASIC {
                        }
                }
 
+               public bool IsLeftHand {
+                       get {
+                               return is_left_hand;
+                       }
+                       set {
+                               is_left_hand = value;
+                       }
+               }
+
+               public bool IsRetvalRequired {
+                       get {
+                               return is_retval_required;
+                       }
+                       set {
+                               is_retval_required = value;
+                       }
+               }
+
+               public bool IsLateBinding {
+                       get {
+                               return is_latebinding;
+                       }
+                       set {
+                               is_latebinding = value;
+                       }
+               }
+
                /// <summary>
                ///   Returns the Parameters (a ParameterData interface) for the
                ///   Method 'mb'
@@ -3871,102 +3851,34 @@ namespace Mono.MonoBASIC {
                        return union;
                }
 
-               /// <summary>
-               ///  Determines is the candidate method, if a params method, is applicable
-               ///  in its expanded form to the given set of arguments
-               /// </summary>
-               static bool IsParamsMethodApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate)
-               {
-                       int arg_count;
-                       
-                       if (arguments == null)
-                               arg_count = 0;
-                       else
-                               arg_count = arguments.Count;
-                       
-                       ParameterData pd = GetParameterData (candidate);
-                       
-                       int pd_count = pd.Count;
-
-                       if (pd_count == 0)
-                               return false;
-                       
-                       if (pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS)
-                               return false;
-                       
-                       if (pd_count - 1 > arg_count)
-                               return false;
-                       
-                       if (pd_count == 1 && arg_count == 0)
-                               return true;
-
-                       //
-                       // If we have come this far, the case which remains is when the number of parameters
-                       // is less than or equal to the argument count.
-                       //
-                       for (int i = 0; i < pd_count - 1; ++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 (a_mod == p_mod) {
-
-                                       if (a_mod == Parameter.Modifier.NONE)
-                                               if (!ImplicitConversionExists (ec, a.Expr, pd.ParameterType (i)))
-                                                       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;
-                               
-                       }
-
-                       Type element_type = pd.ParameterType (pd_count - 1).GetElementType ();
-
-                       for (int i = pd_count - 1; i < arg_count; i++) {
-                               Argument a = (Argument) arguments [i];
-                               
-                               if (!StandardConversionExists (a.Expr, element_type))
-                                       return false;
-                       }
-                       
-                       return true;
-               }
-
 
                protected enum ConversionType { None, Widening, Narrowing };
 
                static ConversionType CheckParameterAgainstArgument (EmitContext ec, ParameterData pd, int i, Argument a, Type ptype)
                {
+                       if (a.ArgType == Argument.AType.NoArg)  {
+                               return ConversionType.Widening;
+                       }
+
                        Parameter.Modifier a_mod = a.GetParameterModifier () &
-                               ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
+                               ~(Parameter.Modifier.REF);
                        Parameter.Modifier p_mod = pd.ParameterModifier (i) &
-                               ~(Parameter.Modifier.OUT | Parameter.Modifier.REF | Parameter.Modifier.OPTIONAL);
+                               ~(Parameter.Modifier.REF | Parameter.Modifier.OPTIONAL);
 
                        if (a_mod == p_mod ||
                                (a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
-                               if (a_mod == Parameter.Modifier.NONE) {
+                               // if (a_mod == Parameter.Modifier.NONE) {
                                        if (! WideningConversionExists (a.Expr, ptype) ) {
+
                                                if (! NarrowingConversionExists (ec, a.Expr, ptype) )
                                                        return ConversionType.None;
                                                else
                                                        return ConversionType.Narrowing;
                                        } else
-                                                       return ConversionType.Widening;
-                               }
+                                               return ConversionType.Widening;
+                                // }
                                
+/*
                                if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
                                        Type pt = pd.ParameterType (i);
                                        
@@ -3977,6 +3889,7 @@ namespace Mono.MonoBASIC {
                                                return ConversionType.None;
                                }
                                return ConversionType.Widening;
+*/
                        } else
                                return ConversionType.None;                                     
                }
@@ -3998,16 +3911,26 @@ namespace Mono.MonoBASIC {
                        return count;
                }
 
+               static ConversionType IsApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate,
+                                                   out bool expanded)
+               {
+                       bool objectArgsPresent;
+                       return IsApplicable (ec, arguments, candidate, out expanded, out objectArgsPresent);
+               }
+
                /// <summary>
                ///  Determines if the candidate method is applicable (section 14.4.2.1)
                ///  to the given set of arguments
                /// </summary>
-               static ConversionType IsApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate, out bool expanded)
+               static ConversionType IsApplicable (EmitContext ec, ArrayList arguments, MethodBase candidate,
+                                                   out bool expanded, out bool objectArgsPresent)
                {
                        int arg_count;
                        Type param_type;
 
-                       expanded = false;
+                       expanded = objectArgsPresent = false;
+                       int num_narr_conv = 0;          // Count the narrowing conversion not involving object
+                                                       // arguments
                        
                        if (arguments == null)
                                arg_count = 0;
@@ -4029,8 +3952,8 @@ namespace Mono.MonoBASIC {
                                if (!HasArrayParameter (pd) && arg_count > pd_count)
                                        return ConversionType.None;
                        }       
+
                        ConversionType result = ConversionType.Widening;
-                       ArrayList newarglist = new ArrayList();
                        if (arg_count > 0) {
                                result = ConversionType.None;
                                int array_param_index = -1;
@@ -4067,7 +3990,7 @@ namespace Mono.MonoBASIC {
                                                        return ConversionType.None;
                                        }
 
-                                       if ((mod & Parameter.Modifier.REF) != 0) {
+                                       if (a.ArgType != Argument.AType.NoArg && (mod & Parameter.Modifier.REF) != 0) {
                                                a = new Argument (a.Expr, Argument.AType.Ref);
                                                if (!a.Resolve(ec,Location.Null))
                                                        return ConversionType.None;
@@ -4082,84 +4005,93 @@ namespace Mono.MonoBASIC {
                                        }
                                        if (match == ConversionType.None)
                                                match = CheckParameterAgainstArgument (ec, pd, i, a, param_type);
-                                       newarglist.Add (a);
                                        if (match == ConversionType.None)
                                                return ConversionType.None;
-                                       if (result == ConversionType.None)
+
+                                       if (match == ConversionType.Narrowing) {
+                                               result = match;
+                                               if (a.Expr.Type == TypeManager.object_type)
+                                                       objectArgsPresent = true;
+                                               else {
+                                                       objectArgsPresent = false;
+                                                       num_narr_conv ++;
+                                               }
+                                       } else if (result == ConversionType.None)
                                                result = match;
-                                       else if (match == ConversionType.Narrowing)
-                                               result = ConversionType.Narrowing;                                      
                                }
                        }
 
-#if false
-                       // 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 (ps != null)
-                                       p = (Parameter) ps.FixedParameters[i];
-
-                               if (a.ArgType == Argument.AType.NoArg){
-                                       a = new Argument (p.ParameterInitializer, Argument.AType.Expression);
-                                       a.Resolve(ec, Location.Null);
-                               }
+                       if (num_narr_conv > 0)  // There were narrowing conversions other than those for object arguments
+                               objectArgsPresent = false;
 
-                               // ToDo - This part is getting resolved second time within this function
-                               // This is a costly operation
-                               // The earlier resoved result should be used here.
-                               // Has to be done during compiler optimization.
-                               if (a.ArgType == Argument.AType.AddressOf) {
-                                       param_type = pd.ParameterType (i);
-                                       bool IsDelegate = TypeManager.IsDelegateType (param_type);
-
-                                       a = new Argument ((Expression) a.Expr, Argument.AType.Expression);
-                                       ArrayList args = new ArrayList();
-                                       args.Add (a);
-                                       string param_name = pd.ParameterDesc(i).Replace('+', '.');
-                                       Expression pname = MonoBASIC.Parser.DecomposeQI (param_name, Location.Null);
-                                                               
-                                       New temp_new = new New ((Expression)pname, args, Location.Null);
-                                       Expression del_temp = temp_new.DoResolve(ec);
-
-                                       if (del_temp == null)
-                                               return ConversionType.None;
+                       return result;
+               }
 
-                                       a = new Argument (del_temp, Argument.AType.Expression);
-                                       if (!a.Resolve(ec, Location.Null))
-                                               return ConversionType.None;
+               internal static ArrayList ReorderArguments (MethodBase mb,
+                                                           ArrayList Arguments,
+                                                           CaseInsensitiveHashtable namedArgs,
+                                                           ref string ErrMsg,
+                                                           Location loc)
+               {
+                       ArrayList orderedArgs = new ArrayList ();
+                       ParameterData pd = GetParameterData (mb);
+                       bool error = false;
+                       for (int index = 0; index < pd.Count; index ++) {
+                               string paramName = pd.ParameterName (index);
+                               if (namedArgs.Contains (paramName)) {
+                                       if ((pd.ParameterModifier (index) & Parameter.Modifier.PARAMS) == Parameter.Modifier.PARAMS) {
+                                               error = true;
+                                               ErrMsg += "\n\t'" + FullMethodDesc (mb) + "': Named argument cannot match a ParamArray parameter";
+                                               continue;
+                                       }
+                                       int argIndex = (int) namedArgs [paramName];
+                                       orderedArgs.Add (Arguments [argIndex]);
+                               } else {
+                                       Parameter.Modifier p_mod = pd.ParameterModifier (index) & Parameter.Modifier.OPTIONAL;
+                                       if (p_mod == Parameter.Modifier.OPTIONAL)
+                                               orderedArgs.Add (new Argument (pd.ParameterName (index), new EmptyExpression (), Argument.AType.NoArg));
+                                        else {
+                                               error = true;
+                                               ErrMsg += "\n\t'" + FullMethodDesc (mb) + "': Argument not specified for parameter '" + paramName + "'";
+                                       }
                                }
+                       }
 
-                               if ((p != null) && ((p.ModFlags & Parameter.Modifier.REF) != 0)) {
-                                       a.ArgType = Argument.AType.Ref;
-                                       a.Resolve(ec, Location.Null);
-                               } else if ((pd.ParameterModifier (i) & 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);
+                       if (Arguments.Count > orderedArgs.Count) {
+                               for (int argIndex = 0; argIndex < Arguments.Count; argIndex ++) {
+                                       string argName = ((Argument) Arguments [argIndex]).ParamName;
+                                       bool found = false;
+                                       for (int paramIndex = 0; paramIndex < pd.Count; paramIndex ++) {
+                                               string paramName = pd.ParameterName (paramIndex);
+                                               if (String.Compare (argName, paramName, true) == 0) {
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (!found) {
+                                               error = true;
+                                               ErrMsg += "\n\t'" + FullMethodDesc (mb) + "': '" + argName + "' is not a parameter";
                                        }
                                }
                        }
-#endif
-                       return result;
+                       if (error)
+                               return null;
+                       return orderedArgs;
                }
                
+/*
                static bool compare_name_filter (MemberInfo m, object filterCriteria)
                {
                        return (m.Name == ((string) filterCriteria));
                }
+*/
+
+               public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me,
+                                                         ref ArrayList Arguments, Location loc)
+               {
+                       bool isLateBindingRequired;
+                       return OverloadResolve (ec, me, ref Arguments, loc, out isLateBindingRequired); 
+               }
 
                // We need an overload for OverloadResolve because Invocation.DoResolve
                // must pass Arguments by reference, since a later call to IsApplicable
@@ -4172,6 +4104,7 @@ namespace Mono.MonoBASIC {
                        return OverloadResolve (ec, me, ref a, loc);    
                }
 
+/*
                static string ToString(MethodBase mbase)
                {
                        if (mbase == null)
@@ -4193,6 +4126,7 @@ namespace Mono.MonoBASIC {
 
                        return mbase.ToString();
                }
+*/
                
                /// <summary>
                ///   Find the Applicable Function Members (7.4.2.1)
@@ -4206,28 +4140,61 @@ namespace Mono.MonoBASIC {
                ///   loc: The location if we want an error to be reported, or a Null
                ///        location for "probing" purposes.
                ///
+               ///   isLateBindingRequired : Flag to indicate that this method call is
+               ///                           is a candidate for late binding. Set to true if
+               ///                           there is atleast one object argument and we get
+               ///                           * Two or more candidates that require widening conv
+               ///                           * Two or more candidates require narrowing conversions
+               ///                             (for object arguments **only**)
                ///   Returns: The MethodBase (either a ConstructorInfo or a MethodInfo)
                ///            that is the best match of me on Arguments.
                ///
                /// </summary>
                public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me,
-                                                         ref ArrayList Arguments, Location loc)
+                                                         ref ArrayList Arguments, Location loc,
+                                                         out bool isLateBindingRequired)
                {
                        MethodBase method = null;
                        int argument_count;
                        ArrayList candidates = new ArrayList ();
+                       ArrayList lateBindingCandidates = new ArrayList ();
                        Hashtable expanded_candidates = new Hashtable();
                        int narrow_count = 0;
                        bool narrowing_candidate = false;
+                       errorMsg = "";
+                       isLateBindingRequired = false;
+                       CaseInsensitiveHashtable namedArgs = new CaseInsensitiveHashtable ();
 
+                       if (Arguments == null)
+                               argument_count = 0;
+                       else
+                               argument_count = Arguments.Count;
+
+                       if (!CheckNamedArguments (Arguments, loc))
+                               return null;
+
+                       if (!GetNamedArgPos (Arguments, ref namedArgs, loc))
+                               return null;
+
+                       ArrayList newarglist = Arguments;
                        foreach (MethodBase candidate in me.Methods){
-                               bool candidate_expanded;
-                               ConversionType m = IsApplicable (ec, Arguments, candidate, out candidate_expanded);
+                               bool candidate_expanded, object_args_present;
+                               newarglist = Arguments;
+                               if (argument_count > 0 && namedArgs.Count != 0) {
+                                       newarglist = ReorderArguments (candidate, Arguments, namedArgs, ref errorMsg, loc);
+                                       if (newarglist == null)
+                                               continue;
+                               }
+
+                               ConversionType m = IsApplicable (ec, newarglist, candidate, out candidate_expanded, out object_args_present);
                                if (candidate_expanded)
                                        expanded_candidates [candidate] = candidate;
                                if (m == ConversionType.None)
                                        continue;
                                else if (m == ConversionType.Narrowing) {
+                                       if (object_args_present)   // if the narrowing conversion was due 
+                                                                  // to the argument being an object
+                                               lateBindingCandidates.Add (candidate);
                                        if (method == null) {
                                                method = candidate;
                                                narrowing_candidate = true;
@@ -4249,22 +4216,24 @@ namespace Mono.MonoBASIC {
                        }
 
                        if (candidates.Count == 0) {
-                               if (narrow_count > 1)
-                                       method = null;
-                               else if (narrow_count == 1)
+                               if (lateBindingCandidates.Count > 1) {
+                                       isLateBindingRequired = true;
+                                       return null;
+                               }
+
+                               if (narrow_count > 1) {
+                                       if (lateBindingCandidates.Count == 1)
+                                               method = (MethodBase) lateBindingCandidates [0];
+                                       else 
+                                               method = null;
+                               } else if (narrow_count == 1)
                                        candidates = null;
                        } else if (candidates.Count == 1) {
                                method = (MethodBase)candidates [0];
                                candidates = null;
                        } else
-                               narrow_count = 0;
-
-                       if (Arguments == null)
-                               argument_count = 0;
-                       else
-                               argument_count = Arguments.Count;
+                               narrow_count  = 0;
 
-                       
                        if (method == null) {
                                //
                                // Okay so we have failed to find anything so we
@@ -4280,7 +4249,7 @@ namespace Mono.MonoBASIC {
 
                                        bool dummy;
                                        if (narrow_count != 0) {
-                                               if (IsApplicable (ec, Arguments, c, out dummy) == ConversionType.None)
+                                               if (IsApplicable (ec, Arguments, c, out dummy) == ConversionType.None)
                                                        continue;
                                                Report.Error (1502, loc,
                                                        "Overloaded match for method '" +
@@ -4302,16 +4271,17 @@ namespace Mono.MonoBASIC {
 
                        if (candidates != null) {
                                foreach (MethodBase candidate in candidates){
-                                       if (candidate == method)
-                                               continue;
+                                       if (candidate == method)
+                                               continue;
+
 
                                        if (BetterFunction (ec, Arguments, candidate, method,
                                                                false, loc) == Applicability.Better) {
-                                               Report.Error (
-                                                       121, loc,
-                                                       "Ambiguous call of '" + me.Name + "' when selecting function due to implicit casts");
+                                               Report.Error (
+                                                       121, loc,
+                                                       "Ambiguous call of '" + me.Name + "' when selecting function due to implicit casts");
                                                return null;
-                                       }
+                                       }
                                }
                        }
 
@@ -4324,7 +4294,14 @@ namespace Mono.MonoBASIC {
 
                        bool chose_params_expanded = expanded_candidates.Contains (method);
 
-                       Arguments = ConstructArgumentList(ec, Arguments, method);
+                       newarglist = Arguments;
+                       if (argument_count > 0 && namedArgs.Count != 0) {
+                               string err = "";
+                               newarglist = ReorderArguments (method, Arguments, namedArgs, ref err, loc);
+                               if (newarglist == null)
+                                       return null;
+                       }
+                       Arguments = ConstructArgumentList(ec, newarglist, namedArgs, method);
                        if (VerifyArgumentsCompat (ec, Arguments, argument_count, method,
                                                   chose_params_expanded, null, loc))
                        {
@@ -4334,19 +4311,70 @@ namespace Mono.MonoBASIC {
                                return null;
                }
 
-               public static ArrayList ConstructArgumentList (EmitContext ec, ArrayList Arguments,     MethodBase method)
+               internal static bool CheckNamedArguments (ArrayList Arguments, Location loc) 
+               {
+                       if (Arguments == null || Arguments.Count == 0)
+                               return true;
+                       
+                       bool namedArgFound = false;
+                       for (int index = 0; index < Arguments.Count; index ++) {
+                               Argument a = (Argument) Arguments [index];
+                               if (a.ParamName == null || a.ParamName == "") {
+                                       if (namedArgFound) {
+                                               Report.Error (30241, loc,
+                                                       "Named argument expected");
+                                               return false;
+                                       }
+                               } else
+                                       namedArgFound = true;
+                       }
+
+                       return true;
+               }
+
+               internal static bool GetNamedArgPos (ArrayList Arguments, ref CaseInsensitiveHashtable namedArgs, Location loc) 
+               {
+                       namedArgs.Clear ();
+                       if (Arguments == null || Arguments.Count == 0)
+                               return true;
+                       for (int index = 0; index < Arguments.Count; index ++) {
+                               Argument a = (Argument) Arguments [index];
+                               if (a.ParamName == null || a.ParamName == "")
+                                       // none of the args are named
+                                       return true;
+                               if (namedArgs.Contains (a.ParamName)) {
+                                       Report.Error (30274, loc, "Parameter '" + a.ParamName +"'already has a matching argument");
+                                       return false;
+                               }
+                               namedArgs.Add (a.ParamName, index);
+                       }
+                       return true;
+               }
+
+               public static ArrayList ConstructArgumentList (EmitContext ec, ArrayList Arguments, CaseInsensitiveHashtable namedArgs, MethodBase method)
                {
                        ArrayList newarglist = new ArrayList();
                        int arg_count = Arguments == null ? 0 : Arguments.Count;
 
                        ParameterData pd = GetParameterData (method);
-                       
-
+                       bool argNamesGiven = (namedArgs.Count > 0);
                        for (int i = 0; i < arg_count; i++) {
                                Argument a = (Argument) Arguments [i];
                                Type param_type = pd.ParameterType (i);
 
                                bool IsDelegate = TypeManager.IsDelegateType (param_type);
+                               if (a.ArgType == Argument.AType.NoArg) {
+                                       Expression pdvalue = pd.DefaultValue (i);
+                                       pdvalue.Resolve (ec);
+                                       if (pdvalue != NullLiteral.Null)
+                                               pdvalue = ConvertImplicit (ec, pdvalue, param_type, Location.Null);;
+                                       if (argNamesGiven)
+                                               a = new Argument (pd.ParameterName (i), pdvalue, Argument.AType.Expression);
+                                       else
+                                               a = new Argument (pdvalue, Argument.AType.Expression);
+                                       a.Resolve (ec, Location.Null);
+                               }
+
                                if (IsDelegate) {       
                                        if (a.ArgType == Argument.AType.AddressOf) {
                                                a = new Argument ((Expression) a.Expr, Argument.AType.Expression);
@@ -4373,11 +4401,18 @@ namespace Mono.MonoBASIC {
                                return newarglist;
 
                        for (int i = arg_count; i < pd.Count; i++) {
+                               Type param_type = pd.ParameterType (i);
                                Expression e = pd.DefaultValue (i);
-                               Argument a = new Argument (e, Argument.AType.Expression);
+                               e.Resolve (ec);
+                               if (e != NullLiteral.Null)
+                                       e = ConvertImplicit (ec, e, param_type, Location.Null);
+                               Argument a = null;
+                               if (argNamesGiven)
+                                       a = new Argument (e, Argument.AType.Expression);
+                               else
+                                       a = new Argument (pd.ParameterName (i), e, Argument.AType.Expression);
                                if ((pd.ParameterModifier (i) & Parameter.Modifier.REF) != 0)
                                        a.ArgType = Argument.AType.Ref;
-                               e.Resolve (ec);
                                a.Resolve (ec, Location.Null);
                                newarglist.Add (a);
                        }
@@ -4419,9 +4454,11 @@ namespace Mono.MonoBASIC {
                                        return false;   
                                }
                                if (pd.ParameterModifier (j) == Parameter.Modifier.PARAMS &&
-                               chose_params_expanded)
+                               chose_params_expanded)
                                        parameter_type = TypeManager.TypeToCoreType (parameter_type.GetElementType ());
-                               if (a.Type != parameter_type){
+                               // By pass conversion for foll. case and handle it in EmitArguments()
+
+                               if (a.ArgType != Argument.AType.Ref && a.Type != parameter_type){
                                        Expression conv;
                                        
                                        conv = ConvertImplicit (ec, a_expr, parameter_type, loc);
@@ -4460,9 +4497,9 @@ namespace Mono.MonoBASIC {
                                }
 
                                Parameter.Modifier a_mod = a.GetParameterModifier () &
-                                       ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
+                                       ~(Parameter.Modifier.REF);
                                Parameter.Modifier p_mod = pd.ParameterModifier (j) &
-                                       ~(Parameter.Modifier.OUT | Parameter.Modifier.REF | Parameter.Modifier.OPTIONAL);
+                                       ~(Parameter.Modifier.REF | Parameter.Modifier.OPTIONAL);
 
                                if (a_mod != p_mod &&
                                    pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS) {
@@ -4482,13 +4519,48 @@ namespace Mono.MonoBASIC {
 
                        return true;
                }
-       
+               
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
                        this.is_left_hand = true;
                        Expression expr_to_return = DoResolve (ec);
+                       if (expr_to_return is PropertyGroupExpr) {
+                               PropertyGroupExpr pe = expr_to_return as PropertyGroupExpr;
+                               pe = (PropertyGroupExpr) pe.ResolveLValue (ec, right_side);
+                               if (pe == null)
+                                       return null;
+                               if (pe.IndexerAccessRequired) {
+                                       if (pe.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_to_return, idxs, expr.Location);
+                                               ArrayAccess aa = new ArrayAccess (ea, expr_to_return.Location);
+                                               expr_to_return = aa.DoResolve(ec);
+                                               expr_to_return.eclass = ExprClass.Variable;
+                                       } else {
+                                               //
+                                               // check whether this is a indexer
+                                               //
+                                               ArrayList idxs = new ArrayList();
+                                               foreach (Argument a in Arguments) {
+                                                       idxs.Add (a.Expr);
+                                               }
+                                               ElementAccess ea = new ElementAccess (expr_to_return, idxs, expr.Location);
+                                               IndexerAccess ia = new IndexerAccess (ea, expr_to_return.Location);
+                                               if (is_left_hand)
+                                                       expr_to_return = ia.DoResolveLValue (ec, right_side);
+                                               else
+                                                       expr_to_return = ia.DoResolve(ec);
+                                       }
+                                       return expr_to_return;
+                               }
+                       }
 
-                       if (expr_to_return is IndexerAccess) {
+                       if (expr_to_return is IndexerAccess && is_left_hand) {
                                IndexerAccess ia = expr_to_return as IndexerAccess;
                                expr_to_return = ia.DoResolveLValue (ec, right_side);
                        }
@@ -4503,29 +4575,53 @@ namespace Mono.MonoBASIC {
                        // trigger the invocation
                        //
                        Expression expr_to_return = null;
+                       Expression temp = null;
 
                        if (expr is BaseAccess)
                                is_base = true;
 
+                       ResolveFlags flags;
                        if ((ec.ReturnType != null) && (expr.ToString() == ec.BlockName)) {
                                ec.InvokingOwnOverload = true;
-                               expr = expr.Resolve (ec, ResolveFlags.MethodGroup);
+                               flags = ResolveFlags.MethodGroup;
+                               temp = expr.Resolve (ec, flags);
                                ec.InvokingOwnOverload = false;
                        }
                        else                            
                        {
                                ec.InvokingOwnOverload = false;
-                               expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
-                       }       
-                       if (expr == null)
+                               flags = ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup;
+                               temp = expr.Resolve (ec, flags);
+                       }
+
+                       if (temp == null) {
+                               if (is_left_hand)
+                                       return null;
+                       
+                               if (expr is MemberAccess) {
+                                       MemberAccess m = expr as MemberAccess;
+                                       if (m.Expr.Type == TypeManager.object_type) {
+                                               StatementSequence etmp = new StatementSequence (ec.CurrentBlock, 
+                                                                               loc, expr, Arguments, 
+                                                                               is_retval_required, is_left_hand);
+                                               if (!etmp.ResolveArguments (ec))
+                                                       return null;
+                                               etmp.GenerateLateBindingStatements();
+                                               this.is_latebinding = true;
+                                               return etmp.Resolve (ec);
+                                       }
+                               }
                                return null;
+                       }
+       
+                       expr = temp;
 
                        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)) 
+                       if (!(expr is MethodGroupExpr || expr is PropertyGroupExpr)) 
                        {
                                Type expr_type = expr.Type;
 
@@ -4556,12 +4652,22 @@ namespace Mono.MonoBASIC {
                        if (expr is MethodGroupExpr) 
                        {
                                MethodGroupExpr mg = (MethodGroupExpr) expr;
-                               method = OverloadResolve (ec, mg, ref Arguments, loc);
-
+                               bool isLateBindingRequired = false;
+                               method = OverloadResolve (ec, mg, ref Arguments, loc, out isLateBindingRequired);
                                if (method == null)
                                {
+                                       if (isLateBindingRequired) {
+                                               Expression type_expr = new TypeOf (Parser.DecomposeQI (mg.DeclaringType.Name, loc), loc);
+                                               StatementSequence etmp = new StatementSequence (ec.CurrentBlock, 
+                                                                       loc, null, mg.Name, type_expr, 
+                                                                       Arguments, is_retval_required, is_left_hand);
+                                               if (! etmp.ResolveArguments (ec))
+                                                       return null;
+                                               etmp.GenerateLateBindingStatements ();
+                                               return etmp.Resolve (ec);
+                                       }
                                        Error (30455,
-                                               "Could not find any applicable function to invoke for this argument list");
+                                               "Could not find any applicable function to invoke for this argument list" + errorMsg);
                                        return null;
                                }
 
@@ -4594,38 +4700,25 @@ namespace Mono.MonoBASIC {
                                return expr_to_return;
                        }
 
-                       if (expr is PropertyExpr) 
+                       if (expr is PropertyGroupExpr) 
                        {
-                               PropertyExpr pe = ((PropertyExpr) expr);
-                               if (pe.PropertyArgs != null)
+                               PropertyGroupExpr pe = ((PropertyGroupExpr) expr);
+                               if (pe.Arguments != null)
                                        goto skip_already_resolved_property;
-                               pe.PropertyArgs = (ArrayList) Arguments;
-                               MethodBase mi = pe.PropertyInfo.GetGetMethod(true);
-
-                               bool expanded = false;
-                               if (IsApplicable(ec, pe.PropertyArgs, mi, out expanded) != ConversionType.None) {
-                                       if(VerifyArgumentsCompat (ec, pe.PropertyArgs,
-                                               pe.PropertyArgs.Count, mi, expanded, null, loc, pe.Name))
-                                       {
-                                               expr_to_return = pe.DoResolve (ec);
-                                               expr_to_return.eclass = ExprClass.PropertyAccess;
-                                               Arguments = new ArrayList ();
-                                               return expr_to_return;
-                                       }
-                                       else
-                                       {
-                                               throw new Exception("Error resolving Property Access expression\n" + pe.ToString());
-                                       }
-                               } else {
-                                       pe.PropertyArgs = new ArrayList ();
-                                       if (VerifyArgumentsCompat (ec, pe.PropertyArgs,
-                                               0, mi, false, null, loc, pe.Name)) {
-                                               expr = pe.DoResolve (ec);
-                                               expr.eclass = ExprClass.PropertyAccess;
-                                       } else {
-                                               throw new Exception("Error resolving Property Access expression\n" + pe.ToString());
-                                       }
+                               if (Arguments != null)
+                                       pe.Arguments = (ArrayList) Arguments.Clone ();
+                               if (is_left_hand)
+                                       return pe;
+                               string name = pe.Name;
+                               pe = (PropertyGroupExpr) pe.Resolve (ec);
+                               if (pe == null) {
+                                       Error (30057, "Property '" + name + "' cannot be invoked with given arguments");
+                                       return null;
                                }
+
+                               if (!pe.IndexerAccessRequired)
+                                       return pe;
+                               expr = pe;
                        }
 
                        skip_already_resolved_property:
@@ -4663,42 +4756,27 @@ namespace Mono.MonoBASIC {
                                        // 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;
+                                       if (! is_left_hand) {
+                                               StatementSequence etmp = new StatementSequence (ec.CurrentBlock, 
+                                                                       loc, ia, Arguments, 
+                                                                       true, false);
+                                               if (!etmp.ResolveArguments (ec))
+                                                       return null;
+                                               etmp.GenerateLateBindingStatements();
+                                               return etmp.Resolve (ec);
+                                       }
+                                       return null;
                                }
                        }
 
                        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 `" +
+               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
@@ -4737,7 +4815,6 @@ namespace Mono.MonoBASIC {
                public static void EmitArguments (EmitContext ec, MethodBase mb, ArrayList arguments)
                {
                        ParameterData pd = GetParameterData (mb);
-
                        //
                        // If we are calling a params method with no arguments, special case it
                        //
@@ -4756,6 +4833,9 @@ namespace Mono.MonoBASIC {
 
                        for (int i = 0; i < top; i++){
                                Argument a = (Argument) arguments [i];
+                               Type parameter_type = pd.ParameterType(i);
+                               Type argtype = a.Type;
+                               Type arg_expr_type = a.Expr.Type;
 
                                if (pd.ParameterModifier (i) == Parameter.Modifier.PARAMS){
                                        //
@@ -4768,18 +4848,48 @@ namespace Mono.MonoBASIC {
                                                EmitParams (ec, i, arguments);
                                        return;
                                }
-
-                               if ((a.ArgType == Argument.AType.Ref || a.ArgType == Argument.AType.Out) &&
-                                       !(a.Expr is IMemoryLocation)) {
-                                       LocalTemporary tmp = new LocalTemporary (ec, pd.ParameterType (i));
+                               if ((a.ArgType == Argument.AType.Ref ) &&
+                                       (parameter_type != arg_expr_type ||
+                                        ! (a.Expr is IMemoryLocation))) {
                                        
-                                       a.Expr.Emit (ec);
-                                       tmp.Store (ec);
-                                       a = new Argument (tmp, a.ArgType);
+                                        LocalTemporary localtmp = new LocalTemporary (ec, parameter_type ); 
+
+                                       if((arg_expr_type != parameter_type) && (a.ArgType == Argument.AType.Ref)) {                                     
+                                               Expression e = ConvertImplicit (ec, a.Expr, parameter_type, Location.Null);
+                                               is_byref_conversion = true;
+                                               e.Emit (ec);
+                                       } else 
+                                               a.Expr.Emit (ec);
+                                       
+
+
+                                       if (tempvars == null)
+                                               tempvars = new ArrayList ();
+                                       if (a.Expr is IMemoryLocation && is_byref_conversion ) {
+                                               Expression conv;
+                                               if(argtype.IsByRef)
+                                                       argtype = argtype.GetElementType();
+                                               conv = ConvertImplicit (ec, localtmp, argtype, Location.Null);
+                                               tempvars.Add (new Assign (a.Expr, conv, Location.Null));
+
+                                       } else if (a.Expr is PropertyGroupExpr) {
+                                               // FIXME: We shouldnt be doing Resolve from inside 'Emit'. 
+                                               // Have to find a way to push this up to 'Resolve'
+                                               Expression conv;
+                                               if(argtype.IsByRef)
+                                                       argtype = argtype.GetElementType();
+                                               conv = ConvertImplicit (ec, localtmp, argtype, Location.Null);
+                                               Assign assgn = new Assign (a.Expr, conv, Location.Null);
+                                               Expression e = assgn.Resolve (ec);
+                                               tempvars.Add (e);
+                                       }
+                                               localtmp.Store (ec);
+                                       a = new Argument (localtmp, a.ArgType);
                                }
-                                           
-                               a.Emit (ec);
-                       }
+                                a.Emit (ec);
+                        }
+
+
 
                        if (pd.Count > top &&
                            pd.ParameterModifier (top) == Parameter.Modifier.PARAMS){
@@ -4818,6 +4928,10 @@ namespace Mono.MonoBASIC {
                {
                        ILGenerator ig = ec.ig;
                        bool struct_call = false;
+                       bool is_myclass = false;
+
+                       if (instance_expr is This && ((This) instance_expr).AccessType == This.TypeOfAccess.MyClass) 
+                               is_myclass = true;
 
                        Type decl_type = method.DeclaringType;
 
@@ -4924,7 +5038,7 @@ namespace Mono.MonoBASIC {
 
                        EmitArguments (ec, method, Arguments);
 
-                       if (is_static || struct_call || is_base)
+                       if (is_static || struct_call || is_base || is_myclass)
                        {
                                if (method is MethodInfo) 
                                {
@@ -4942,6 +5056,7 @@ namespace Mono.MonoBASIC {
                        }
                }
                
+/*
                static void EmitPropertyArgs (EmitContext ec, ArrayList prop_args)
                {
                        int top = prop_args.Count;
@@ -4952,11 +5067,12 @@ namespace Mono.MonoBASIC {
                                a.Emit (ec);
                        }
                }
+*/
 
                public override void Emit (EmitContext ec)
                {
                        MethodGroupExpr mg = (MethodGroupExpr) this.expr;
-
                        EmitCall (
                                ec, is_base, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
                }
@@ -4970,8 +5086,20 @@ namespace Mono.MonoBASIC {
                        //
                        if (method is MethodInfo){
                                Type ret = ((MethodInfo)method).ReturnType;
-                               if (TypeManager.TypeToCoreType (ret) != TypeManager.void_type)
+                               if ((TypeManager.TypeToCoreType (ret) != TypeManager.void_type) && !this.is_latebinding) {
                                        ec.ig.Emit (OpCodes.Pop);
+
+                                       if (tempvars != null) {
+                                               foreach (Expression s in tempvars) {
+                                                       if (s is ExpressionStatement)
+                                                               ((ExpressionStatement) s).EmitStatement (ec);
+                                                       else
+                                                               s.Emit (ec);
+                                               }
+                                               tempvars.Clear ();
+                                       }
+                               }
+                               
                        }
                }
        }
@@ -5429,6 +5557,7 @@ namespace Mono.MonoBASIC {
                        }
                }
 
+/*
                void Error_NegativeArrayIndex ()
                {
                        Error (284, "Can not create array with a negative size");
@@ -5480,6 +5609,7 @@ namespace Mono.MonoBASIC {
 
                        return target;
                }
+*/
 
                //
                // Creates the type of the array
@@ -5938,18 +6068,36 @@ namespace Mono.MonoBASIC {
        /// </summary>
        public class This : Expression, IAssignMethod, IMemoryLocation, IVariable {
 
+               public enum TypeOfAccess : byte {
+                       Me, MyClass
+               }
+
                Block block;
                VariableInfo vi;
+               TypeOfAccess access_type;
                
+               public This (TypeOfAccess access_type, Block block, Location loc)
+               {
+                       this.loc = loc;
+                       this.block = block;
+                       this.access_type = access_type;
+               }
+
                public This (Block block, Location loc)
                {
                        this.loc = loc;
                        this.block = block;
+                       this.access_type = TypeOfAccess.Me;
                }
 
                public This (Location loc)
                {
                        this.loc = loc;
+                       this.access_type = TypeOfAccess.Me;
+               }
+
+               public TypeOfAccess AccessType { 
+                       get { return access_type; }
                }
 
                public bool IsAssigned (EmitContext ec, Location loc)
@@ -6139,6 +6287,9 @@ namespace Mono.MonoBASIC {
                public readonly string Identifier;
                Expression expr;
                Expression member_lookup;
+               bool is_invocation = false;
+               bool is_left_hand;
+               bool is_addressof = false;
                
                public MemberAccess (Expression expr, string id, Location l)
                {
@@ -6147,6 +6298,38 @@ namespace Mono.MonoBASIC {
                        loc = l;
                }
 
+               public MemberAccess (Expression expr, string id, Location l, bool isInvocation)
+               {
+                       this.expr = expr;
+                       Identifier = id;
+                       loc = l;
+                       is_invocation = isInvocation;
+               }
+
+               public bool IsInvocation {
+                       get {
+                               return is_invocation;
+                       }
+                       set {
+                               is_invocation = value;
+                       }
+               }
+
+               public bool IsAddressOf {
+                       set {
+                               is_addressof = value;
+                       }
+               }
+
+               public bool IsLeftHand {
+                       get {
+                               return is_left_hand;
+                       }
+                       set {
+                               is_left_hand = value;
+                       }
+               }
+
                public Expression Expr {
                        get {
                                return expr;
@@ -6182,7 +6365,8 @@ namespace Mono.MonoBASIC {
                                                              Expression left, Location loc,
                                                              Expression left_original)
                {
-                       bool left_is_type, left_is_explicit;
+                        bool left_is_type, left_is_explicit;
+                       
 
                        // If 'left' is null, then we're called from SimpleNameResolve and this is
                        // a member in the currently defining class.
@@ -6205,14 +6389,27 @@ namespace Mono.MonoBASIC {
                                
                                if (fi is FieldBuilder) {
                                        Const c = TypeManager.LookupConstant ((FieldBuilder) fi);
-                                       
                                        if (c != null) {
-                                               //object o = c.LookupConstantValue (ec);
+                                        object o;
+                                        if (!c.LookupConstantValue (out o, ec))
+                                                return null;
+                                       
                                                object real_value = ((Constant) c.Expr).GetValue ();
+                                         Expression exp = Constantify (real_value, fi.FieldType);
 
-                                               return Constantify (real_value, fi.FieldType);
-                                       }
+                                        return exp;
+                                       }
                                }
+                               
+                                 // IsInitOnly is because of MS compatibility, I don't know why but they emit decimal constant as InitOnly
+                        
+                       if (fi.IsInitOnly && !(fi is FieldBuilder) && fi.FieldType == TypeManager.decimal_type) {
+                                object[] attrs = fi.GetCustomAttributes (TypeManager.decimal_constant_attribute_type, false);
+                                if (attrs.Length == 1)
+                                        return new DecimalConstant (((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value);
+                        }
+
+
 
                                if (fi.IsLiteral) {
                                        Type t = fi.FieldType;
@@ -6266,17 +6463,31 @@ namespace Mono.MonoBASIC {
                        if (member_lookup is IMemberExpr) {
                                IMemberExpr me = (IMemberExpr) member_lookup;
 
-                               if (left_is_type){
-                                       MethodGroupExpr mg = me as MethodGroupExpr;
-                                       if ((mg != null) && left_is_explicit && left.Type.IsInterface)
-                                               mg.IsExplicitImpl = left_is_explicit;
-
-                                       if (!me.IsStatic){
-                                               if (IdenticalNameAndTypeName (ec, left_original, loc))
-                                                       return member_lookup;
-
-                                               SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
-                                               return null;
+                               if (left_is_type) {
+                                       if (me is PropertyGroupExpr) {
+                                               PropertyGroupExpr mg = me as PropertyGroupExpr;
+                                               if ((mg != null) && left_is_explicit && left.Type.IsInterface)
+                                                       mg.IsExplicitImpl = left_is_explicit;
+       
+                                               if (!me.IsStatic){
+                                                       if (IdenticalNameAndTypeName (ec, left_original, loc))
+                                                               return member_lookup;
+       
+                                                       SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
+                                                       return null;
+                                               }
+                                       } else {
+                                               MethodGroupExpr mg = me as MethodGroupExpr;
+                                               if ((mg != null) && left_is_explicit && left.Type.IsInterface)
+                                                       mg.IsExplicitImpl = left_is_explicit;
+       
+                                               if (!me.IsStatic){
+                                                       if (IdenticalNameAndTypeName (ec, left_original, loc))
+                                                               return member_lookup;
+       
+                                                       SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
+                                                       return null;
+                                               }
                                        }
 
                                } else {
@@ -6349,6 +6560,7 @@ namespace Mono.MonoBASIC {
                                SimpleName child_expr = (SimpleName) expr;
 
                                Expression new_expr = new SimpleName (child_expr.Name + "." + Identifier, loc);
+                               ((SimpleName) new_expr).IsInvocation = is_invocation;
 
                                if ((flags & ResolveFlags.MaskExprClass) == ResolveFlags.Type)
                                        return new_expr.Resolve (ec, flags);
@@ -6392,7 +6604,6 @@ namespace Mono.MonoBASIC {
                        }
 
                        member_lookup = MemberLookup (ec, expr_type, Identifier, loc);
-
                        if (member_lookup == null)
                        {
                                // Error has already been reported.
@@ -6407,8 +6618,28 @@ namespace Mono.MonoBASIC {
                                        expr_type, expr_type, AllMemberTypes, AllBindingFlags |
                                        BindingFlags.NonPublic, Identifier);
                                        
-                               if (lookup == null)
-                                       Error (30456, "'" + expr_type + "' does not contain a definition for '" + Identifier + "'");
+                               if (lookup == null) {
+                                       if (expr_type != TypeManager.object_type)
+                                               Error (30456, "'" + expr_type + "' does not contain a definition for '" + Identifier + "'");
+                                       // If this came as a part of Invocation, 
+                                       // Since argumets are not known, return null, 
+                                       // let Invocation's Resolve take care
+                                       if (is_invocation)
+                                               return null;
+
+                                       else if (! is_left_hand) {
+                                               StatementSequence etmp = new StatementSequence (ec.CurrentBlock, 
+                                                                               loc, this, null, 
+                                                                               true, is_left_hand);
+                                               etmp.GenerateLateBindingStatements();
+                                               return etmp.Resolve (ec);
+                                       } 
+
+                                       // if the expression is a left hand side of an assignment,
+                                       // return null, as we dont know the RHS
+                                       // Let assign take care of Late Binding
+                                       return null;
+                               }
                                else
                                {
                                        if ((expr_type != ec.ContainerType) &&
@@ -6468,6 +6699,14 @@ namespace Mono.MonoBASIC {
                        if (member_lookup == null)
                                return null;
 
+                       if ((member_lookup is MethodGroupExpr) && ! is_invocation && !is_addressof) {
+                               Expression inv = new Invocation (this, new ArrayList (), loc);
+                               return inv.Resolve (ec);
+                       }
+
+                       if (member_lookup is PropertyGroupExpr && is_invocation) // As we dont know the arguments yet
+                               return member_lookup;
+
                        // The following DoResolve/DoResolveLValue will do the definite assignment
                        // check.
                        if (right_side != null)
@@ -6475,6 +6714,7 @@ namespace Mono.MonoBASIC {
                        else
                                member_lookup = member_lookup.DoResolve (ec);
 
+
                        return member_lookup;
                }
 
@@ -7135,10 +7375,6 @@ namespace Mono.MonoBASIC {
                                                return ix;
                                }
                        }
-
-                       Report.Error (21, loc,
-                                     "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
-                                     "' does not have any indexers defined");
                        return null;
                }
        }
@@ -7153,7 +7389,7 @@ namespace Mono.MonoBASIC {
                MethodInfo get, set;
                Indexers ilist;
                ArrayList set_arguments;
-               bool is_base_indexer;
+               //bool is_base_indexer;
 
                protected Type indexer_type;
                protected Type current_type;
@@ -7170,11 +7406,23 @@ namespace Mono.MonoBASIC {
                                         Location loc)
                {
                        this.instance_expr = instance_expr;
-                       this.is_base_indexer = is_base_indexer;
+                       //this.is_base_indexer = is_base_indexer;
                        this.eclass = ExprClass.Value;
                        this.loc = loc;
                }
 
+               public Expression Instance {
+                       get {
+                               return instance_expr;
+                       }
+               }
+
+               public ArrayList Arguments {
+                       get {
+                               return arguments;
+                       }
+               }
+
                protected virtual bool CommonResolve (EmitContext ec)
                {
                        indexer_type = instance_expr.Type;
@@ -7194,10 +7442,18 @@ namespace Mono.MonoBASIC {
                        //
                        // This is a group of properties, piles of them.  
 
-                       if (ilist == null)
+                       if (ilist == null) {
                                ilist = Indexers.GetIndexersForType (
                                        current_type, indexer_type, loc);
 
+                               if (ilist == null && indexer_type != TypeManager.object_type) {
+                                       Report.Error (21, loc,
+                                               "Type '" + TypeManager.MonoBASIC_Name (indexer_type) +
+                                               "' does not have any indexers defined");
+                                       return null;
+                               }
+                       }
+
                        //
                        // Step 2: find the proper match
                        //
@@ -7206,8 +7462,9 @@ namespace Mono.MonoBASIC {
                                        ec, new MethodGroupExpr (ilist.getters, loc), arguments, loc);
 
                        if (get == null){
-                               Error (30524, "indexer can not be used in this context, because " +
-                                      "it lacks a 'get' accessor");
+                               if (instance_expr.Type != TypeManager.object_type)
+                                       Error (30524, "indexer can not be used in this context, because " +
+                                               "it lacks a 'get' accessor");
                                return null;
                        }
 
@@ -7228,9 +7485,16 @@ namespace Mono.MonoBASIC {
 
                        Type right_type = right_side.Type;
 
-                       if (ilist == null)
+                       if (ilist == null) {
                                ilist = Indexers.GetIndexersForType (
                                        current_type, indexer_type, loc);
+                               if (ilist == null && indexer_type != TypeManager.object_type) {
+                                       Report.Error (21, loc,
+                                               "Type '" + TypeManager.MonoBASIC_Name (indexer_type) +
+                                               "' does not have any indexers defined");
+                                       return null;
+                               }
+                       }
 
                        if (ilist != null && ilist.setters != null && ilist.setters.Count > 0){
                                set_arguments = (ArrayList) arguments.Clone ();