2006-08-13 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / mbas / statement.cs
index 889bcc852fab7aff74ae93be46291cefe7063fec..0914861a26983cae60906917d5bd93e3f00365eb 100644 (file)
@@ -72,8 +72,8 @@ namespace Mono.MonoBASIC {
                ///    Encapsulates the emission of a boolean test and jumping to a
                ///    destination.
                ///
-               ///    This will emit the bool expression in `bool_expr' and if
-               ///    `target_is_for_true' is true, then the code will generate a 
+               ///    This will emit the bool expression in 'bool_expr' and if
+               ///    'target_is_for_true' is true, then the code will generate a 
                ///    brtrue to the target.   Otherwise a brfalse. 
                /// </remarks>
                public static void EmitBoolExpression (EmitContext ec, Expression bool_expr,
@@ -431,8 +431,8 @@ namespace Mono.MonoBASIC {
                                ig.Emit (OpCodes.Br, ec.LoopBegin);
                                        
                                //
-                               // Inform that we are infinite (ie, `we return'), only
-                               // if we do not `break' inside the code.
+                               // Inform that we are infinite (ie, 'we return'), only
+                               // if we do not 'break' inside the code.
                                //
                                ret = may_return == false;
                                ig.MarkLabel (ec.LoopEnd);
@@ -812,6 +812,7 @@ namespace Mono.MonoBASIC {
                
                public Return (Expression expr, Location l)
                {
+                       expr = Parser.SetValueRequiredFlag (expr);
                        Expr = expr;
                        loc = l;
                }
@@ -829,8 +830,10 @@ namespace Mono.MonoBASIC {
                        if (ec.CurrentBranching.InTryBlock ())
                                ec.CurrentBranching.AddFinallyVector (vector);
 
-                       vector.Returns = FlowReturns.ALWAYS;
-                       vector.Breaks = FlowReturns.ALWAYS;
+                       if (! ec.InTry && ! ec.InCatch) {
+                               vector.Returns = FlowReturns.ALWAYS;
+                               vector.Breaks = FlowReturns.ALWAYS;
+                       }
                        return true;
                }
                
@@ -848,7 +851,7 @@ namespace Mono.MonoBASIC {
                                }
                        } else {
                                if (Expr == null){
-                                       Report.Error (126, loc, "An object of type `" +
+                                       Report.Error (126, loc, "An object of type '" +
                                                      TypeManager.MonoBASIC_Name (ec.ReturnType) + "' is " +
                                                      "expected for the return statement");
                                        return true;
@@ -888,10 +891,11 @@ namespace Mono.MonoBASIC {
                public override bool Resolve (EmitContext ec)
                {
                        label = block.LookupLabel (target);
+
                        if (label == null){
                                Report.Error (
                                        30132, loc,
-                                       "No such label `" + target + "' in this scope");
+                                       "No such label '" + target + "' in this scope");
                                return false;
                        }
 
@@ -899,8 +903,8 @@ namespace Mono.MonoBASIC {
                        if (!label.IsDefined)
                                label.AddUsageVector (ec.CurrentBranching.CurrentUsageVector);
 
-                       ec.CurrentBranching.CurrentUsageVector.Breaks = FlowReturns.ALWAYS;
-
+                        ec.CurrentBranching.CurrentUsageVector.Breaks = FlowReturns.ALWAYS;
+                       label.AddReference ();
                        return true;
                }
                
@@ -931,7 +935,7 @@ namespace Mono.MonoBASIC {
 
        public class LabeledStatement : Statement {
                public readonly Location Location;
-               //string label_name;
+               string label_name;
                bool defined;
                bool referenced;
                Label label;
@@ -940,15 +944,22 @@ namespace Mono.MonoBASIC {
                
                public LabeledStatement (string label_name, Location l)
                {
-                       //this.label_name = label_name;
+                       this.label_name = label_name;
                        this.Location = l;
                }
+               
+               public string LabelName {
+                       get {
+                               return label_name;
+                       }
+               }
 
                public Label LabelTarget (EmitContext ec)
                {
-                       if (defined)
+                       if (defined) 
                                return label;
                        label = ec.ig.DefineLabel ();
+
                        defined = true;
 
                        return label;
@@ -972,12 +983,14 @@ namespace Mono.MonoBASIC {
                                vectors = new ArrayList ();
 
                        vectors.Add (vector.Clone ());
+
                }
 
                public override bool Resolve (EmitContext ec)
                {
-                       if (vectors != null)
+                       if (vectors != null) {
                                ec.CurrentBranching.CurrentUsageVector.MergeJumpOrigins (vectors);
+                       }
                        else {
                                ec.CurrentBranching.CurrentUsageVector.Breaks = FlowReturns.NEVER;
                                ec.CurrentBranching.CurrentUsageVector.Returns = FlowReturns.NEVER;
@@ -985,6 +998,7 @@ namespace Mono.MonoBASIC {
 
                        referenced = true;
 
+
                        return true;
                }
 
@@ -995,11 +1009,15 @@ namespace Mono.MonoBASIC {
 
                        return false;
                }
+               public void AddReference ()
+                {
+                        referenced = true;
+                }
        }
        
 
        /// <summary>
-       ///   `goto default' statement
+       ///   'goto default' statement
        /// </summary>
        public class GotoDefault : Statement {
                
@@ -1031,7 +1049,7 @@ namespace Mono.MonoBASIC {
        }
 
        /// <summary>
-       ///   `goto case' statement
+       ///   'goto case' statement
        /// </summary>
        public class GotoCase : Statement {
                Expression expr;
@@ -1271,11 +1289,8 @@ namespace Mono.MonoBASIC {
                                }
                        
                                if (ec.InTry || ec.InCatch) {
-                                       if (!ec.HasReturnLabel) {
-                                               ec.ReturnLabel = ec.ig.DefineLabel ();
-                                               ec.HasReturnLabel = true;
-                                       }
-                                       ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
+                                       if (ec.HasExitLabel)
+                                               ec.ig.Emit (OpCodes.Leave, ec.ExitLabel);
                                } else {
                                        if(type == ExitType.SUB) {   
                                                 ec.ig.Emit (OpCodes.Ret);
@@ -1367,7 +1382,8 @@ namespace Mono.MonoBASIC {
        //   current one.
        // </summary>
        public class MyBitVector {
-               public readonly int Count;
+               private int count;
+               public int Count { get { return count; } }
                public readonly MyBitVector InheritsFrom;
 
                bool is_dirty;
@@ -1380,7 +1396,7 @@ namespace Mono.MonoBASIC {
                public MyBitVector (MyBitVector InheritsFrom, int Count)
                {
                        this.InheritsFrom = InheritsFrom;
-                       this.Count = Count;
+                       this.count = Count;
                }
 
                // <summary>
@@ -1399,12 +1415,12 @@ namespace Mono.MonoBASIC {
                }
 
                // <summary>
-               //   Get/set bit `index' in the bit vector.
+               //   Get/set bit 'index' in the bit vector.
                // </summary>
                public bool this [int index]
                {
                        get {
-                               if (index > Count)
+                               if (index > count)
                                        throw new ArgumentOutOfRangeException ();
 
                                // We're doing a "copy-on-write" strategy here; as long
@@ -1425,7 +1441,7 @@ namespace Mono.MonoBASIC {
                        }
 
                        set {
-                               if (index > Count)
+                               if (index > count)
                                        throw new ArgumentOutOfRangeException ();
 
                                // Only copy the vector if we're actually modifying it.
@@ -1449,7 +1465,7 @@ namespace Mono.MonoBASIC {
                }
 
                // <summary>
-               //   Performs an `or' operation on the bit vector.  The `new_vector' may have a
+               //   Performs an 'or' operation on the bit vector.  The 'new_vector' may have a
                //   different size than the current one.
                // </summary>
                public void Or (MyBitVector new_vector)
@@ -1469,7 +1485,7 @@ namespace Mono.MonoBASIC {
                }
 
                // <summary>
-               //   Perfonrms an `and' operation on the bit vector.  The `new_vector' may have
+               //   Perfonrms an 'and' operation on the bit vector.  The 'new_vector' may have
                //   a different size than the current one.
                // </summary>
                public void And (MyBitVector new_vector)
@@ -1504,6 +1520,18 @@ namespace Mono.MonoBASIC {
 
                        return retval;
                }
+               
+               public void ExpandBy(int howMany)
+               {
+                       if (howMany < 1)
+                               throw new ArgumentException("howMany");
+                       initialize_vector();
+                       count = vector.Count + howMany;
+                       BitArray newVector = new BitArray(count, false);
+                       for (int i = 0; i < vector.Count; i++)
+                                       newVector [i] = vector [i];
+                       vector = newVector;
+               }
 
                BitArray Vector {
                        get {
@@ -1632,7 +1660,7 @@ namespace Mono.MonoBASIC {
                int id;
 
                // <summary>
-               //   Performs an `And' operation on the FlowReturns status
+               //   Performs an 'And' operation on the FlowReturns status
                //   (for instance, a block only returns ALWAYS if all its siblings
                //   always return).
                // </summary>
@@ -1689,6 +1717,12 @@ namespace Mono.MonoBASIC {
                        //   The number of locals in this block.
                        // </summary>
                        public readonly int CountLocals;
+                       
+                       // <summary>
+                       //   The number of locals in this block added after starting usage track.
+                       // </summary>
+                       public int ExtraLocals  { get { return locals.Count - CountLocals; } } 
+
 
                        // <summary>
                        //   If not null, then we inherit our state from this vector and do a
@@ -1737,6 +1771,11 @@ namespace Mono.MonoBASIC {
                                : this (parent, parent.CountParameters, parent.CountLocals)
                        { }
 
+                       public void AddExtraLocals(int howMany)
+                       {
+                               locals.ExpandBy(howMany);
+                       }
+                       
                        // <summary>
                        //   This does a deep copy of the usage vector.
                        // </summary>
@@ -1754,7 +1793,7 @@ namespace Mono.MonoBASIC {
                        }
 
                        // 
-                       // State of parameter `number'.
+                       // State of parameter 'number'.
                        //
                        public bool this [int number]
                        {
@@ -1778,8 +1817,8 @@ namespace Mono.MonoBASIC {
                        }
 
                        //
-                       // State of the local variable `vi'.
-                       // If the local variable is a struct, use a non-zero `field_idx'
+                       // State of the local variable 'vi'.
+                       // If the local variable is a struct, use a non-zero 'field_idx'
                        // to check an individual field in it.
                        //
                        public bool this [VariableInfo vi, int field_idx]
@@ -1886,7 +1925,7 @@ namespace Mono.MonoBASIC {
                                        if (!child.is_finally) {
                                                if (child.Breaks != FlowReturns.UNREACHABLE) {
                                                        // If Returns is already set, perform an
-                                                       // `And' operation on it, otherwise just set just.
+                                                       // 'And' operation on it, otherwise just set just.
                                                        if (!new_returns_set) {
                                                                new_returns = child.Returns;
                                                                new_returns_set = true;
@@ -1896,7 +1935,7 @@ namespace Mono.MonoBASIC {
                                                }
 
                                                // If Breaks is already set, perform an
-                                               // `And' operation on it, otherwise just set just.
+                                               // 'And' operation on it, otherwise just set just.
                                                if (!new_breaks_set) {
                                                        new_breaks = child.Breaks;
                                                        new_breaks_set = true;
@@ -1929,7 +1968,7 @@ namespace Mono.MonoBASIC {
                                        //    6   Console.WriteLine (a);
                                        //
                                        // The if block in lines 3-4 always returns, so we must not look
-                                       // at the initialization of `a' in line 4 - thus it'll still be
+                                       // at the initialization of 'a' in line 4 - thus it'll still be
                                        // uninitialized in line 6.
                                        //
                                        // On the other hand, the following is allowed:
@@ -1941,7 +1980,7 @@ namespace Mono.MonoBASIC {
                                        //    5      return;
                                        //    6   Console.WriteLine (a);
                                        //
-                                       // Here, `a' is initialized in line 3 and we must not look at
+                                       // Here, 'a' is initialized in line 3 and we must not look at
                                        // line 5 since it always returns.
                                        // 
                                        if (child.is_finally) {
@@ -1968,7 +2007,7 @@ namespace Mono.MonoBASIC {
                                                        new_locals.Or (child.locals);
                                                }
 
-                                               // An `out' parameter must be assigned in all branches which do
+                                               // An 'out' parameter must be assigned in all branches which do
                                                // not always throw an exception.
                                                if (parameters != null) {
                                                        if (child.Breaks != FlowReturns.EXCEPTION) {
@@ -2058,11 +2097,11 @@ namespace Mono.MonoBASIC {
 
                        // <summary>
                        //   Tells control flow analysis that the current code position may be reached with
-                       //   a forward jump from any of the origins listed in `origin_vectors' which is a
+                       //   a forward jump from any of the origins listed in 'origin_vectors' which is a
                        //   list of UsageVectors.
                        //
                        //   This is used when resolving forward gotos - in the following example, the
-                       //   variable `a' is uninitialized in line 8 becase this line may be reached via
+                       //   variable 'a' is uninitialized in line 8 becase this line may be reached via
                        //   the goto in line 4:
                        //
                        //      1     int a;
@@ -2119,7 +2158,7 @@ namespace Mono.MonoBASIC {
                                Report.Debug (1, "MERGING FINALLY ORIGIN DONE", this);
                        }
                        // <summary>
-                       //   Performs an `or' operation on the locals and the parameters.
+                       //   Performs an 'or' operation on the locals and the parameters.
                        // </summary>
                        public void Or (UsageVector new_vector)
                        {
@@ -2129,7 +2168,7 @@ namespace Mono.MonoBASIC {
                        }
 
                        // <summary>
-                       //   Performs an `and' operation on the locals.
+                       //   Performs an 'and' operation on the locals.
                        // </summary>
                        public void AndLocals (UsageVector new_vector)
                        {
@@ -2193,7 +2232,7 @@ namespace Mono.MonoBASIC {
                }
 
                // <summary>
-               //   Creates a new flow branching for `block'.
+               //   Creates a new flow branching for 'block'.
                //   This is used from Block.Resolve to create the top-level branching of
                //   the block.
                // </summary>
@@ -2230,8 +2269,8 @@ namespace Mono.MonoBASIC {
                }
 
                // <summary>
-               //   Creates a new flow branching which is contained in `parent'.
-               //   You should only pass non-null for the `block' argument if this block
+               //   Creates a new flow branching which is contained in 'parent'.
+               //   You should only pass non-null for the 'block' argument if this block
                //   introduces any new variables - in this case, we need to create a new
                //   usage vector with a different size than our parent's one.
                // </summary>
@@ -2289,7 +2328,7 @@ namespace Mono.MonoBASIC {
                }
 
                // <summary>
-               //   Creates a sibling for a `finally' block.
+               //   Creates a sibling for a 'finally' block.
                // </summary>
                public void CreateSiblingForFinally ()
                {
@@ -2477,7 +2516,7 @@ namespace Mono.MonoBASIC {
 
                        case FlowBranchingType.LOOP_BLOCK:
                                // The code following a loop is reachable unless the loop always
-                               // returns or it's an infinite loop without any `break's in it.
+                               // returns or it's an infinite loop without any 'break's in it.
                                reachable = !CurrentUsageVector.AlwaysReturns &&
                                        (CurrentUsageVector.Breaks != FlowReturns.UNREACHABLE);
                                break;
@@ -2639,16 +2678,24 @@ namespace Mono.MonoBASIC {
                public Expression Type;
                public LocalBuilder LocalBuilder;
                public Type VariableType;
+               public string Alias;
+               FieldBase FieldAlias;
                public readonly string Name;
                public readonly Location Location;
                public readonly int Block;
-
+               
                public int Number;
                
                public bool Used;
                public bool Assigned;
                public bool ReadOnly;
                
+               public VariableInfo (Expression type, string name, int block, Location l, string Alias)
+                       : this (type, name, block, l)
+               {
+                       this.Alias = Alias;
+               }
+               
                public VariableInfo (Expression type, string name, int block, Location l)
                {
                        Type = type;
@@ -2658,6 +2705,12 @@ namespace Mono.MonoBASIC {
                        Location = l;
                }
 
+               public VariableInfo (TypeContainer tc, int block, Location l, string Alias)
+                       : this (tc, block, l)
+               {
+                       this.Alias = Alias;
+               }
+               
                public VariableInfo (TypeContainer tc, int block, Location l)
                {
                        VariableType = tc.TypeBuilder;
@@ -2681,7 +2734,7 @@ namespace Mono.MonoBASIC {
 
                        MyStructInfo struct_info = StructInfo;
                        if ((struct_info == null) || (struct_info.HasNonPublicFields && (Name != null))) {
-                               Report.Error (165, loc, "Use of unassigned local variable `" + Name + "'");
+                               Report.Error (165, loc, "Use of unassigned local variable '" + Name + "'");
                                ec.CurrentBranching.SetVariableAssigned (this);
                                return false;
                        }
@@ -2692,771 +2745,102 @@ namespace Mono.MonoBASIC {
                                if (!ec.CurrentBranching.IsVariableAssigned (this, i+1)) {
                                        if (Name != null) {
                                                Report.Error (165, loc,
-                                                             "Use of unassigned local variable `" +
+                                                             "Use of unassigned local variable '" +
                                                              Name + "'");
                                                ec.CurrentBranching.SetVariableAssigned (this);
                                                return false;
-                                       }
-
-                                       FieldInfo field = struct_info [i];
-                                       Report.Error (171, loc,
-                                                     "Field `" + TypeManager.MonoBASIC_Name (VariableType) +
-                                                     "." + field.Name + "' must be fully initialized " +
-                                                     "before control leaves the constructor");
-                                       return false;
-                               }
-                       }
-*/
-                       return true;
-               }
-
-               public bool IsFieldAssigned (EmitContext ec, string name, Location loc)
-               {
-                       if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsVariableAssigned (this) ||
-                           (struct_info == null))
-                               return true;
-
-                       int field_idx = StructInfo [name];
-                       if (field_idx == 0)
-                               return true;
-
-                       if (!ec.CurrentBranching.IsVariableAssigned (this, field_idx)) {
-                               Report.Error (170, loc,
-                                             "Use of possibly unassigned field `" + name + "'");
-                               ec.CurrentBranching.SetVariableAssigned (this, field_idx);
-                               return false;
-                       }
-
-                       return true;
-               }
-
-               public void SetAssigned (EmitContext ec)
-               {
-                       if (ec.DoFlowAnalysis)
-                               ec.CurrentBranching.SetVariableAssigned (this);
-               }
-
-               public void SetFieldAssigned (EmitContext ec, string name)
-               {
-                       if (ec.DoFlowAnalysis && (struct_info != null))
-                               ec.CurrentBranching.SetVariableAssigned (this, StructInfo [name]);
-               }
-
-               public bool Resolve (DeclSpace decl)
-               {
-                       if (struct_info != null)
-                               return true;
-
-                       if (VariableType == null)
-                               VariableType = decl.ResolveType (Type, false, Location);
-
-                       if (VariableType == null)
-                               return false;
-
-                       struct_info = MyStructInfo.GetStructInfo (VariableType);
-
-                       return true;
-               }
-
-               public void MakePinned ()
-               {
-                       TypeManager.MakePinned (LocalBuilder);
-               }
-
-               public override string ToString ()
-               {
-                       return "VariableInfo (" + Number + "," + Type + "," + Location + ")";
-               }
-       }
-               
-       /// <summary>
-       ///   Block represents a C# block.
-       /// </summary>
-       ///
-       /// <remarks>
-       ///   This class is used in a number of places: either to represent
-       ///   explicit blocks that the programmer places or implicit blocks.
-       ///
-       ///   Implicit blocks are used as labels or to introduce variable
-       ///   declarations.
-       /// </remarks>
-       public class Block : Statement {
-               public readonly Block     Parent;
-               public readonly bool      Implicit;
-               public readonly Location  StartLocation;
-               public Location           EndLocation;
-
-               //
-               // The statements in this block
-               //
-               public ArrayList statements;
-
-               //
-               // An array of Blocks.  We keep track of children just
-               // to generate the local variable declarations.
-               //
-               // Statements and child statements are handled through the
-               // statements.
-               //
-               ArrayList children;
-               
-               //
-               // Labels.  (label, block) pairs.
-               //
-               CaseInsensitiveHashtable labels;
-
-               //
-               // Keeps track of (name, type) pairs
-               //
-               CaseInsensitiveHashtable variables;
-
-               //
-               // Keeps track of constants
-               CaseInsensitiveHashtable constants;
-
-               //
-               // Maps variable names to ILGenerator.LocalBuilders
-               //
-               //CaseInsensitiveHashtable local_builders;
-
-               // to hold names of variables required for late binding
-               public const string lateBindingArgs = "1_LBArgs";
-               public const string lateBindingArgNames = "1_LBArgsNames";
-               public const string lateBindingCopyBack = "1_LBCopyBack";
-
-               bool isLateBindingRequired = false;
-
-               bool used = false;
-
-               static int id;
-
-               int this_id;
-               
-               public Block (Block parent)
-                       : this (parent, false, Location.Null, Location.Null)
-               { }
-
-               public Block (Block parent, bool implicit_block)
-                       : this (parent, implicit_block, Location.Null, Location.Null)
-               { }
-
-               public Block (Block parent, bool implicit_block, Parameters parameters)
-                       : this (parent, implicit_block, parameters, Location.Null, Location.Null)
-               { }
-
-               public Block (Block parent, Location start, Location end)
-                       : this (parent, false, start, end)
-               { }
-
-               public Block (Block parent, Parameters parameters, Location start, Location end)
-                       : this (parent, false, parameters, start, end)
-               { }
-
-               public Block (Block parent, bool implicit_block, Location start, Location end)
-                       : this (parent, implicit_block, Parameters.EmptyReadOnlyParameters,
-                               start, end)
-               { }
-
-               public Block (Block parent, bool implicit_block, Parameters parameters,
-                             Location start, Location end)
-               {
-                       if (parent != null)
-                               parent.AddChild (this);
-                       else {
-                               // Top block
-                               // Add variables that may be required for late binding
-                               variables = new CaseInsensitiveHashtable ();
-                               ArrayList rank_specifier = new ArrayList ();
-                               ArrayList element = new ArrayList ();
-                               element.Add (new EmptyExpression ());
-                               rank_specifier.Add (element);
-                               Expression e = Mono.MonoBASIC.Parser.DecomposeQI ("System.Object[]", start);
-                               AddVariable (e, Block.lateBindingArgs, null, start);
-                               e = Mono.MonoBASIC.Parser.DecomposeQI ("System.String[]", start);
-                               AddVariable (e, Block.lateBindingArgNames, null, start);
-                               e = Mono.MonoBASIC.Parser.DecomposeQI ("System.Boolean[]", start);
-                               AddVariable (e, Block.lateBindingCopyBack, null, start);
-                       }
-                       
-                       this.Parent = parent;
-                       this.Implicit = implicit_block;
-                       this.parameters = parameters;
-                       this.StartLocation = start;
-                       this.EndLocation = end;
-                       this.loc = start;
-                       this_id = id++;
-                       statements = new ArrayList ();
-               }
-
-               public bool IsLateBindingRequired {
-                       get {
-                               return isLateBindingRequired;
-                       }
-                       set {
-                               isLateBindingRequired = value;
-                       }
-               }
-
-               public int ID {
-                       get {
-                               return this_id;
-                       }
-               }
-
-               void AddChild (Block b)
-               {
-                       if (children == null)
-                               children = new ArrayList ();
-                       
-                       children.Add (b);
-               }
-
-               public void SetEndLocation (Location loc)
-               {
-                       EndLocation = loc;
-               }
-
-               /// <summary>
-               ///   Adds a label to the current block. 
-               /// </summary>
-               ///
-               /// <returns>
-               ///   false if the name already exists in this block. true
-               ///   otherwise.
-               /// </returns>
-               ///
-               public bool AddLabel (string name, LabeledStatement target)
-               {
-                       if (labels == null)
-                               labels = new CaseInsensitiveHashtable ();
-                       if (labels.Contains (name))
-                               return false;
-                       
-                       labels.Add (name, target);
-                       return true;
-               }
-
-               public LabeledStatement LookupLabel (string name)
-               {
-                       if (labels != null){
-                               if (labels.Contains (name))
-                                       return ((LabeledStatement) labels [name]);
-                       }
-
-                       if (Parent != null)
-                               return Parent.LookupLabel (name);
-
-                       return null;
-               }
-
-               VariableInfo this_variable = null;
-
-               // <summary>
-               //   Returns the "this" instance variable of this block.
-               //   See AddThisVariable() for more information.
-               // </summary>
-               public VariableInfo ThisVariable {
-                       get {
-                               if (this_variable != null)
-                                       return this_variable;
-                               else if (Parent != null)
-                                       return Parent.ThisVariable;
-                               else
-                                       return null;
-                       }
-               }
-
-               Hashtable child_variable_names;
-
-               // <summary>
-               //   Marks a variable with name @name as being used in a child block.
-               //   If a variable name has been used in a child block, it's illegal to
-               //   declare a variable with the same name in the current block.
-               // </summary>
-               public void AddChildVariableName (string name)
-               {
-                       if (child_variable_names == null)
-                               child_variable_names = new CaseInsensitiveHashtable ();
-
-                       if (!child_variable_names.Contains (name))
-                               child_variable_names.Add (name, true);
-               }
-
-               // <summary>
-               //   Marks all variables from block @block and all its children as being
-               //   used in a child block.
-               // </summary>
-               public void AddChildVariableNames (Block block)
-               {
-                       if (block.Variables != null) {
-                               foreach (string name in block.Variables.Keys)
-                                       AddChildVariableName (name);
-                       }
-
-                       foreach (Block child in block.children) {
-                               if (child.Variables != null) {
-                                       foreach (string name in child.Variables.Keys)
-                                               AddChildVariableName (name);
-                               }
-                       }
-               }
-
-               // <summary>
-               //   Checks whether a variable name has already been used in a child block.
-               // </summary>
-               public bool IsVariableNameUsedInChildBlock (string name)
-               {
-                       if (child_variable_names == null)
-                               return false;
-
-                       return child_variable_names.Contains (name);
-               }
-
-               // <summary>
-               //   This is used by non-static `struct' constructors which do not have an
-               //   initializer - in this case, the constructor must initialize all of the
-               //   struct's fields.  To do this, we add a "this" variable and use the flow
-               //   analysis code to ensure that it's been fully initialized before control
-               //   leaves the constructor.
-               // </summary>
-               public VariableInfo AddThisVariable (TypeContainer tc, Location l)
-               {
-                       if (this_variable != null)
-                               return this_variable;
-
-                       this_variable = new VariableInfo (tc, ID, l);
-
-                       if (variables == null)
-                               variables = new CaseInsensitiveHashtable ();
-                       variables.Add ("this", this_variable);
-
-                       return this_variable;
-               }
-
-               public VariableInfo AddVariable (Expression type, string name, Parameters pars, Location l)
-               {
-                       if (variables == null)
-                               variables = new CaseInsensitiveHashtable ();
-
-                       VariableInfo vi = GetVariableInfo (name);
-                       if (vi != null) {
-                               if (vi.Block != ID)
-                                       Report.Error (30616, l, "A local variable named `" + name + "' " +
-                                                     "cannot be declared in this scope since it would " +
-                                                     "give a different meaning to `" + name + "', which " +
-                                                     "is already used in a `parent or current' scope to " +
-                                                     "denote something else");
-                               else
-                                       Report.Error (30290, l, "A local variable `" + name + "' is already " +
-                                                     "defined in this scope");
-                               return null;
-                       }
-
-                       if (IsVariableNameUsedInChildBlock (name)) {
-                               Report.Error (136, l, "A local variable named `" + name + "' " +
-                                             "cannot be declared in this scope since it would " +
-                                             "give a different meaning to `" + name + "', which " +
-                                             "is already used in a `child' scope to denote something " +
-                                             "else");
-                               return null;
-                       }
-
-                       if (pars != null) {
-                               int idx = 0;
-                               Parameter p = pars.GetParameterByName (name, out idx);
-                               if (p != null) {
-                                       Report.Error (30616, l, "A local variable named `" + name + "' " +
-                                                     "cannot be declared in this scope since it would " +
-                                                     "give a different meaning to `" + name + "', which " +
-                                                     "is already used in a `parent or current' scope to " +
-                                                     "denote something else");
-                                       return null;
-                               }
-                       }
-                       
-                       vi = new VariableInfo (type, name, ID, l);
-
-                       variables.Add (name, vi);
-
-                       if (variables_initialized)
-                               throw new Exception ();
-
-                       // Console.WriteLine ("Adding {0} to {1}", name, ID);
-                       return vi;
-               }
-
-               public bool AddConstant (Expression type, string name, Expression value, Parameters pars, Location l)
-               {
-                       if (AddVariable (type, name, pars, l) == null)
-                               return false;
-                       
-                       if (constants == null)
-                               constants = new CaseInsensitiveHashtable ();
-
-                       constants.Add (name, value);
-                       return true;
-               }
-
-               public Hashtable Variables {
-                       get {
-                               return variables;
-                       }
-               }
-
-               public VariableInfo GetVariableInfo (string name)
-               {
-                       if (variables != null) {
-                               object temp;
-                               temp = variables [name];
-
-                               if (temp != null){
-                                       return (VariableInfo) temp;
-                               }
-                       }
-
-                       if (Parent != null)
-                               return Parent.GetVariableInfo (name);
-
-                       return null;
-               }
-               
-               public Expression GetVariableType (string name)
-               {
-                       VariableInfo vi = GetVariableInfo (name);
-
-                       if (vi != null)
-                               return vi.Type;
-
-                       return null;
-               }
-
-               public Expression GetConstantExpression (string name)
-               {
-                       if (constants != null) {
-                               object temp;
-                               temp = constants [name];
-                               
-                               if (temp != null)
-                                       return (Expression) temp;
-                       }
-                       
-                       if (Parent != null)
-                               return Parent.GetConstantExpression (name);
-
-                       return null;
-               }
-               
-               /// <summary>
-               ///   True if the variable named @name has been defined
-               ///   in this block
-               /// </summary>
-               public bool IsVariableDefined (string name)
-               {
-                       // Console.WriteLine ("Looking up {0} in {1}", name, ID);
-                       if (variables != null) {
-                               if (variables.Contains (name))
-                                       return true;
-                       }
-                       
-                       if (Parent != null)
-                               return Parent.IsVariableDefined (name);
-
-                       return false;
-               }
-
-               /// <summary>
-               ///   True if the variable named @name is a constant
-               ///  </summary>
-               public bool IsConstant (string name)
-               {
-                       Expression e = null;
-                       
-                       e = GetConstantExpression (name);
-                       
-                       return e != null;
-               }
-               
-               /// <summary>
-               ///   Use to fetch the statement associated with this label
-               /// </summary>
-               public Statement this [string name] {
-                       get {
-                               return (Statement) labels [name];
-                       }
-               }
-
-               Parameters parameters = null;
-               public Parameters Parameters {
-                       get {
-                               if (Parent != null)
-                                       return Parent.Parameters;
-
-                               return parameters;
-                       }
-               }
-
-               /// <returns>
-               ///   A list of labels that were not used within this block
-               /// </returns>
-               public string [] GetUnreferenced ()
-               {
-                       // FIXME: Implement me
-                       return null;
-               }
-
-               public void AddStatement (Statement s)
-               {
-                       statements.Add (s);
-                       used = true;
-               }
-
-               public bool Used {
-                       get {
-                               return used;
-                       }
-               }
-
-               public void Use ()
-               {
-                       used = true;
-               }
-
-               bool variables_initialized = false;
-               int count_variables = 0, first_variable = 0;
-
-               void UpdateVariableInfo (EmitContext ec)
-               {
-                       DeclSpace ds = ec.DeclSpace;
-
-                       first_variable = 0;
-
-                       if (Parent != null)
-                               first_variable += Parent.CountVariables;
-
-                       count_variables = first_variable;
-                       if (variables != null) {
-                               foreach (VariableInfo vi in variables.Values) {
-                                       if (!vi.Resolve (ds)) {
-                                               vi.Number = -1;
-                                               continue;
-                                       }
-
-                                       vi.Number = ++count_variables;
-
-                                       if (vi.StructInfo != null)
-                                               count_variables += vi.StructInfo.Count;
-                               }
-                       }
-
-                       variables_initialized = true;
-               }
-
-               //
-               // <returns>
-               //   The number of local variables in this block
-               // </returns>
-               public int CountVariables
-               {
-                       get {
-                               if (!variables_initialized)
-                                       throw new Exception ();
-
-                               return count_variables;
-                       }
-               }
-
-               /// <summary>
-               ///   Emits the variable declarations and labels.
-               /// </summary>
-               /// <remarks>
-               ///   tc: is our typecontainer (to resolve type references)
-               ///   ig: is the code generator:
-               ///   toplevel: the toplevel block.  This is used for checking 
-               ///             that no two labels with the same name are used.
-               /// </remarks>
-               public void EmitMeta (EmitContext ec, Block toplevel)
-               {
-                       //DeclSpace ds = ec.DeclSpace;
-                       ILGenerator ig = ec.ig;
-
-                       if (!variables_initialized)
-                               UpdateVariableInfo (ec);
-
-                       //
-                       // Process this block variables
-                       //
-                       if (variables != null){
-                               //local_builders = new CaseInsensitiveHashtable ();
-                               
-                               foreach (DictionaryEntry de in variables){
-                                       string name = (string) de.Key;
-                                       /*
-                                       if (!isLateBindingRequired) {
-                                               if (name.Equals (Block.lateBindingArgs) || 
-                                                   name.Equals (Block.lateBindingArgNames) ||
-                                                   name.Equals (Block.lateBindingCopyBack))
-                                                       continue;
-                                       }
-                                       */
-                                       VariableInfo vi = (VariableInfo) de.Value;
-
-                                       if (vi.VariableType == null)
-                                               continue;
-
-                                       vi.LocalBuilder = ig.DeclareLocal (vi.VariableType);
-
-                                       if (CodeGen.SymbolWriter != null)
-                                               vi.LocalBuilder.SetLocalSymInfo (name);
-
-                                       if (constants == null)
-                                               continue;
-
-                                       Expression cv = (Expression) constants [name];
-                                       if (cv == null)
-                                               continue;
-
-                                       Expression e = cv.Resolve (ec);
-                                       if (e == null)
-                                               continue;
-
-                                       if (!(e is Constant)){
-                                               Report.Error (133, vi.Location,
-                                                             "The expression being assigned to `" +
-                                                             name + "' must be constant (" + e + ")");
-                                               continue;
-                                       }
-
-                                       constants.Remove (name);
-                                       constants.Add (name, e);
-                               }
-                       }
-
-                       //
-                       // Now, handle the children
-                       //
-                       if (children != null){
-                               foreach (Block b in children)
-                                       b.EmitMeta (ec, toplevel);
-                       }
-               }
-
-               public void UsageWarning ()
-               {
-                       string name;
-                       
-                       if (variables != null){
-                               foreach (DictionaryEntry de in variables){
-                                       VariableInfo vi = (VariableInfo) de.Value;
-                                       
-                                       if (vi.Used)
-                                               continue;
-                                       
-                                       name = (string) de.Key;
-                                               
-                                       if (vi.Assigned){
-                                               Report.Warning (
-                                                       219, vi.Location, "The variable `" + name +
-                                                       "' is assigned but its value is never used");
-                                       } else {
-                                               Report.Warning (
-                                                       168, vi.Location, "The variable `" +
-                                                       name +
-                                                       "' is declared but never used");
-                                       } 
+                                       }
+
+                                       FieldInfo field = struct_info [i];
+                                       Report.Error (171, loc,
+                                                     "Field '" + TypeManager.MonoBASIC_Name (VariableType) +
+                                                     "." + field.Name + "' must be fully initialized " +
+                                                     "before control leaves the constructor");
+                                       return false;
                                }
                        }
-
-                       if (children != null)
-                               foreach (Block b in children)
-                                       b.UsageWarning ();
+*/
+                       return true;
                }
 
-               bool has_ret = false;
-
-               public override bool Resolve (EmitContext ec)
+               public bool IsFieldAssigned (EmitContext ec, string name, Location loc)
                {
-                       Block prev_block = ec.CurrentBlock;
-                       bool ok = true;
+                       if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsVariableAssigned (this) ||
+                           (struct_info == null))
+                               return true;
 
-                       ec.CurrentBlock = this;
+                       int field_idx = StructInfo [name];
+                       if (field_idx == 0)
+                               return true;
 
-                       if (!variables_initialized)
-                               UpdateVariableInfo (ec);
+                       if (!ec.CurrentBranching.IsVariableAssigned (this, field_idx)) {
+                               Report.Error (170, loc,
+                                             "Use of possibly unassigned field '" + name + "'");
+                               ec.CurrentBranching.SetVariableAssigned (this, field_idx);
+                               return false;
+                       }
 
-                       ec.StartFlowBranching (this);
+                       return true;
+               }
 
-                       Report.Debug (1, "RESOLVE BLOCK", StartLocation, ec.CurrentBranching);
+               public void SetAssigned (EmitContext ec)
+               {
+                       if (ec.DoFlowAnalysis)
+                               ec.CurrentBranching.SetVariableAssigned (this);
+               }
 
-                       ArrayList new_statements = new ArrayList ();
-                       bool unreachable = false, warning_shown = false;
+               public void SetFieldAssigned (EmitContext ec, string name)
+               {
+                       if (ec.DoFlowAnalysis && (struct_info != null))
+                               ec.CurrentBranching.SetVariableAssigned (this, StructInfo [name]);
+               }
 
-                       foreach (Statement s in statements){
-                               if (unreachable && !(s is LabeledStatement)) {
-                                       if (!warning_shown && !(s is EmptyStatement)) {
-                                               warning_shown = true;
-                                               Warning_DeadCodeFound (s.loc);
+               public FieldBase GetFieldAlias (EmitContext ec)  {
+                       if ( this.FieldAlias != null )
+                               return this.FieldAlias;
+                       else
+                       {
+                               ArrayList fields = ec.TypeContainer.Fields;
+                                for (int i = 0; i < fields.Count; i++) 
+                               {
+                                       if (((Field) fields[i]).Name == this.Alias) 
+                                       {
+                                               this.FieldAlias = (Field) fields[i];
+                                               break;
                                        }
-                                       continue;
-                               }
-
-                               if (s.Resolve (ec) == false) {
-                                       ok = false;
-                                       continue;
-                               }
-
-                               if (s is LabeledStatement)
-                                       unreachable = false;
-                               else
-                                       unreachable = ! ec.CurrentBranching.IsReachable ();
-
-                               new_statements.Add (s);
-                       }
-
-                       statements = new_statements;
-
-                       Report.Debug (1, "RESOLVE BLOCK DONE", StartLocation, ec.CurrentBranching);
-
-                       FlowReturns returns = ec.EndFlowBranching ();
-                       ec.CurrentBlock = prev_block;
+                               }
+                               return this.FieldAlias;
+                       }
+               }
+               
+               public bool Resolve (DeclSpace decl)
+               {
+                       if (struct_info != null)
+                               return true;
 
-                       // If we're a non-static `struct' constructor which doesn't have an
-                       // initializer, then we must initialize all of the struct's fields.
-                       if ((this_variable != null) && (returns != FlowReturns.EXCEPTION) &&
-                           !this_variable.IsAssigned (ec, loc))
-                               ok = false;
+                       if (VariableType == null)
+                               VariableType = decl.ResolveType (Type, false, Location);
 
-                       if ((labels != null) && (RootContext.WarningLevel >= 2)) {
-                               foreach (LabeledStatement label in labels.Values)
-                                       if (!label.HasBeenReferenced)
-                                               Report.Warning (164, label.Location,
-                                                               "This label has not been referenced");
-                       }
+                       if (VariableType == null)
+                               return false;
 
-                       if ((returns == FlowReturns.ALWAYS) ||
-                           (returns == FlowReturns.EXCEPTION) ||
-                           (returns == FlowReturns.UNREACHABLE))
-                               has_ret = true;
+                       struct_info = MyStructInfo.GetStructInfo (VariableType);
 
-                       return ok;
+                       return true;
                }
-               
-               protected override bool DoEmit (EmitContext ec)
-               {
-                       Block prev_block = ec.CurrentBlock;
 
-                       ec.CurrentBlock = this;
+               public void MakePinned ()
+               {
+                       TypeManager.MakePinned (LocalBuilder);
+               }
 
-                       ec.Mark (StartLocation);
-                       foreach (Statement s in statements)
-                               s.Emit (ec);
-                               
-                       ec.Mark (EndLocation); 
-                       
-                       ec.CurrentBlock = prev_block;
-                       return has_ret;
+               public override string ToString ()
+               {
+                       return "VariableInfo (" + Number + "," + Type + "," + Location + ")";
                }
        }
 
+               
        public class StatementSequence : Expression {
                Block stmtBlock;
                ArrayList args, originalArgs;
@@ -3466,6 +2850,7 @@ namespace Mono.MonoBASIC {
                bool isIndexerAccess;
                string memberName;
                Expression type_expr;
+               bool is_resolved = false;
 
                public StatementSequence (Block parent, Location loc, Expression expr) 
                        : this (parent, loc, expr, null)
@@ -3542,10 +2927,13 @@ namespace Mono.MonoBASIC {
                
                public override Expression DoResolve (EmitContext ec)
                {
+                       if (is_resolved)
+                               return this;
                        if (!stmtBlock.Resolve (ec))
                                return null;
                        eclass = ExprClass.Value;
                        type = TypeManager.object_type;
+                       is_resolved = true;
                        return this;
                }
 
@@ -3958,7 +3346,7 @@ namespace Mono.MonoBASIC {
 
                                if (converted != null){
                                        Report.Error (-12, loc, "More than one conversion to an integral " +
-                                                     " type exists for type `" +
+                                                     " type exists for type '" +
                                                      TypeManager.MonoBASIC_Name (Expr.Type)+"'");
                                        return null;
                                } else
@@ -3972,7 +3360,7 @@ namespace Mono.MonoBASIC {
                void error152 (string n)
                {
                        Report.Error (
-                               152, "The label `" + n + ":' " +
+                               152, "The label '" + n + ":' " +
                                "is already present on this switch statement");
                }
                
@@ -4298,7 +3686,7 @@ namespace Mono.MonoBASIC {
                }
                //
                // This simple emit switch works, but does not take advantage of the
-               // `switch' opcode. 
+               // 'switch' opcode. 
                // TODO: remove non-string logic from here
                // TODO: binary search strings?
                //
@@ -4548,7 +3936,7 @@ namespace Mono.MonoBASIC {
                        
                        if (type.IsValueType){
                                Report.Error (30582, loc, "lock statement requires the expression to be " +
-                                             " a reference type (type is: `" +
+                                             " a reference type (type is: '" +
                                              TypeManager.MonoBASIC_Name (type) + "'");
                                return false;
                        }
@@ -5079,11 +4467,13 @@ namespace Mono.MonoBASIC {
                protected override bool DoEmit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
-                       Label finish = ig.DefineLabel ();;
                        bool returns;
 
                        ec.TryCatchLevel++;
-                       ig.BeginExceptionBlock ();
+                       Label finish = ig.BeginExceptionBlock ();
+                       ec.HasExitLabel = true;
+                       ec.ExitLabel = finish;
+
                        bool old_in_try = ec.InTry;
                        ec.InTry = true;
                        returns = Block.Emit (ec);
@@ -5153,7 +4543,6 @@ namespace Mono.MonoBASIC {
 
                        ec.InCatch = old_in_catch;
 
-                       ig.MarkLabel (finish);
                        if (Fini != null){
                                ig.BeginFinallyBlock ();
                                bool old_in_finally = ec.InFinally;
@@ -5168,8 +4557,204 @@ namespace Mono.MonoBASIC {
                        if (!returns || ec.InTry || ec.InCatch)
                                return returns;
 
+                       return true;
+               }
+       }
+       
+       public  class Pending_Assign {
+               Statement assign;
+               Block block_to_be_inserted;
+               int statement_index;
+               
+               public Pending_Assign (Block block, Statement assign, int index)
+               {
+                       this.assign = assign;
+                       this.block_to_be_inserted = block;
+                       this.statement_index = index;
+               }
+
+               public  void AddAssign()
+               {
+                       block_to_be_inserted.statements.Insert( statement_index, assign );
+               }       
+       }
+       
+       public class On_Error : Statement {
+               public readonly Block method_block;
+               ArrayList targets;
+               LabeledStatement[] labeledstatements;
+               
+               public On_Error (Block method_block, Location l)
+               {       
+                       //Goto
+                       this.method_block = method_block;
+                       base.loc = l;
+                       targets = new ArrayList();
+               }
+
+               public int AddTarget ( string target )
+               {                               
+                       int i = targets.IndexOf( target ) ;
+                       
+                       if ( i == -1 ) 
+                               return targets.Add ( target );
+                       else
+                               return i;
+               }
+
+               public ArrayList Targets {
+                       get {
+                               return targets;
+                       }
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       this.labeledstatements = new LabeledStatement[targets.Count];
+                       
+                       bool ok = true;
+                       
+                       ec.StartFlowBranching (FlowBranchingType.EXCEPTION, method_block.StartLocation);
+
+                       Report.Debug (1, "START OF TRY BLOCK", method_block.StartLocation);
+
+                       bool old_in_try = ec.InTry;
+                       ec.InTry = true;
+
+                       if (!method_block.Resolve (ec))
+                               ok = false;
+
+                       ec.InTry = old_in_try;
+
+                       FlowBranching.UsageVector vector = ec.CurrentBranching.CurrentUsageVector;
+
+                       ec.EndFlowBranching ();
+
+                       ec.CurrentBranching.CurrentUsageVector.Or (vector);
+
+                       Report.Debug (1, "END OF TRY", ec.CurrentBranching);
+
+                       //This statement has more than one label in cases of more than one 'on error goto' specification.
+                       for ( int i = 0 ; i < targets.Count ; i++ )
+                       {
+                               labeledstatements[i] = method_block.Parent.LookupLabel ((string) targets[i]);
+
+                               // If this is a forward goto.
+                               if (!labeledstatements[i].IsDefined)
+                                       labeledstatements[i].AddUsageVector (ec.CurrentBranching.CurrentUsageVector);
+
+                               labeledstatements[i].AddReference ();
+                       }
+                       ec.CurrentBranching.CurrentUsageVector.Breaks = FlowReturns.ALWAYS;
+                       
+                       return ok;
+               }
+               protected override bool DoEmit (EmitContext ec)
+               {       
+                       ILGenerator ig = ec.ig;
+                               
+                       //Try
+
+                       bool returns;
+
+                       ec.TryCatchLevel++;
+                       
+                       Label finish = ig.BeginExceptionBlock ();
+                               ec.HasExitLabel = true;
+                               ec.ExitLabel = finish;
+                               
+                               bool old_in_try = ec.InTry;
+                               ec.InTry = true;
+                               returns = method_block.Emit (ec);
+                               ec.InTry = old_in_try;
+                               bool old_in_catch = ec.InCatch;
+                               ec.InCatch = true;
+
+                       Label error = ig.DefineLabel();
+                       Label endfilter = ig.DefineLabel();
+                       Label verification = ig.DefineLabel();
+                       
+                       ig.BeginExceptFilterBlock();
+                               ig.Emit (OpCodes.Isinst, Type.GetType("System.Exception") );
+                               ig.Emit (OpCodes.Brtrue_S, verification );
+
+                               ig.Emit (OpCodes.Br_S, error);
+                       
+                               ig.MarkLabel ( verification );  
+                               ig.Emit (OpCodes.Ldloc_0);
+                               ig.Emit (OpCodes.Brfalse_S, error);
+                               
+                               ig.Emit (OpCodes.Ldloc_1);
+                               ig.Emit (OpCodes.Brtrue_S, error);
+
+                               ig.Emit (OpCodes.Ldc_I4_1);
+                               ig.Emit (OpCodes.Br_S, endfilter);
+                               
+                               ig.MarkLabel (error);   
+                               ig.Emit (OpCodes.Ldc_I4_0);
+
+                               ig.MarkLabel ( endfilter );     
+                       
+                       
+                       Label endcatch = ig.DefineLabel();              
+                       Label verification2 = ig.DefineLabel();
+                       
+                       ig.BeginCatchBlock (null);
+                               ig.Emit (OpCodes.Castclass, Type.GetType("System.Exception"));
+                               ig.Emit (OpCodes.Dup);
+
+                               Type t = typeof(Microsoft.VisualBasic.CompilerServices.ProjectData);
+                               MethodInfo mi = t.GetMethod("SetProjectError", new Type[] { typeof(System.Exception) } );
+                               ig.Emit (OpCodes.Call, mi);
+                               ig.Emit (OpCodes.Stloc_3);
+                               ig.Emit (OpCodes.Ldloc_1);
+                               ig.Emit (OpCodes.Brfalse_S, verification2 );
+                               ig.Emit (OpCodes.Leave_S, finish );
+                               ig.MarkLabel ( verification2 );
+                               ig.Emit (OpCodes.Ldc_I4_M1);
+                               ig.Emit (OpCodes.Stloc_1);
+                               ig.Emit (OpCodes.Ldloc_0);
+
+                               Label[] lbswitch = new Label[targets.Count + 1];
+                               for ( int i = 0; i <= targets.Count; i++ )
+                                       lbswitch[i] = ig.DefineLabel();
+                               
+                               ig.Emit (OpCodes.Switch, lbswitch);     
+                               ig.MarkLabel ( lbswitch[0] ) ;
+                               ig.Emit (OpCodes.Leave_S, endcatch);    
+                                                               
+                               Label[] labels = new Label[targets.Count];
+                               for ( int i = 0; i < targets.Count; i++ )
+                               {
+                                       labels[i] = labeledstatements[i].LabelTarget(ec);
+
+                                       ig.MarkLabel ( lbswitch[i+1] ) ;
+                                       ig.Emit ( OpCodes.Leave, labels[i] );
+                               }
+
+                               ig.MarkLabel ( endcatch );
+                               ig.Emit ( OpCodes.Rethrow );    
+
+                       ec.InCatch = old_in_catch;
+
+                       ig.EndExceptionBlock ();
+                       ec.TryCatchLevel--;
+
+                       Label end = ig.DefineLabel();
+                       //ig.MarkLabel ( finish ) ;
+                       ig.Emit (OpCodes.Ldloc_1);
+                       ig.Emit (OpCodes.Brfalse_S, end );
+                               
+                       mi = t.GetMethod("ClearProjectError");
+                       ig.Emit (OpCodes.Call, mi);
+
+                       ig.MarkLabel(end) ;
+                       
+                       if (!returns)
+                               return returns;
+
                        // Unfortunately, System.Reflection.Emit automatically emits a leave
-                       // to the end of the finally block.  This is a problem if `returns'
+                       // to the end of the finally block.  This is a problem if 'returns'
                        // is true since we may jump to a point after the end of the method.
                        // As a workaround, emit an explicit ret here.
 
@@ -5179,6 +4764,7 @@ namespace Mono.MonoBASIC {
 
                        return true;
                }
+               
        }
 
        public class Using : Statement {
@@ -5412,6 +4998,19 @@ namespace Mono.MonoBASIC {
                        if (expr == null)
                                return false;
 
+                       if ( variable.VariableInfo.Alias != null )
+                       {
+                               FieldBase fb = variable.VariableInfo.GetFieldAlias(ec);
+
+                               if ( fb == null )
+                               {
+                                       Report.Error (451, loc,"Name '" + variable.VariableInfo.Name  + "' is not declared.");
+                                       return false;
+                               }
+                               else
+                               type = fb.Type;
+                       }
+                                               
                        var_type = ec.DeclSpace.ResolveType (type, false, loc);
                        if (var_type == null)
                                return false;
@@ -5474,7 +5073,7 @@ namespace Mono.MonoBASIC {
                }
                
                //
-               // Retrieves a `public bool MoveNext ()' method from the Type `t'
+               // Retrieves a 'public bool MoveNext ()' method from the Type 't'
                //
                static MethodInfo FetchMethodMoveNext (Type t)
                {
@@ -5501,7 +5100,7 @@ namespace Mono.MonoBASIC {
                }
                
                //
-               // Retrieves a `public T get_Current ()' method from the Type `t'
+               // Retrieves a 'public T get_Current ()' method from the Type 't'
                //
                static MethodInfo FetchMethodGetCurrent (Type t)
                {
@@ -5599,7 +5198,7 @@ namespace Mono.MonoBASIC {
 
                        //
                        // Ok, we can access it, now make sure that we can do something
-                       // with this `GetEnumerator'
+                       // with this 'GetEnumerator'
                        //
 
                        if (mi.ReturnType == TypeManager.ienumerator_type ||
@@ -5645,7 +5244,7 @@ namespace Mono.MonoBASIC {
                 void error1579 (Type t)
                 {
                         Report.Error (1579, loc,
-                                      "foreach statement cannot operate on variables of type `" +
+                                      "foreach statement cannot operate on variables of type '" +
                                       t.FullName + "' because that class does not provide a " +
                                       " GetEnumerator method or it is inaccessible");
                 }
@@ -5705,7 +5304,7 @@ namespace Mono.MonoBASIC {
 
                //
                // FIXME: possible optimization.
-               // We might be able to avoid creating `empty' if the type is the sam
+               // We might be able to avoid creating 'empty' if the type is the sam
                //
                bool EmitCollectionForeach (EmitContext ec)
                {
@@ -5753,9 +5352,25 @@ namespace Mono.MonoBASIC {
                        ig.Emit (OpCodes.Ldloc, enumerator);
                        ig.Emit (OpCodes.Callvirt, hm.move_next);
                        ig.Emit (OpCodes.Brfalse, end_try);
+                       
+                       
+                       FieldBase fb = null;
+                       if ( variable.VariableInfo.Alias != null )
+                       {
+                               fb = variable.VariableInfo.GetFieldAlias(ec);
+                               
+                               if( (fb.ModFlags & Modifiers.STATIC) == 0 )
+                                       ig.Emit (OpCodes.Ldarg_0);
+                       }       
+                                       
                        ig.Emit (OpCodes.Ldloc, enumerator);
                        ig.Emit (OpCodes.Callvirt, hm.get_current);
-                       variable.EmitAssign (ec, conv);
+                       
+                       if ( fb == null)
+                               variable.EmitAssign (ec, conv);
+                       else
+                               variable.EmitAssign (ec, conv, fb);
+                       
                        statement.Emit (ec);
                        ig.Emit (OpCodes.Br, ec.LoopBegin);
                        ig.MarkLabel (end_try);
@@ -5795,7 +5410,7 @@ namespace Mono.MonoBASIC {
 
                //
                // FIXME: possible optimization.
-               // We might be able to avoid creating `empty' if the type is the sam
+               // We might be able to avoid creating 'empty' if the type is the sam
                //
                bool EmitArrayForeach (EmitContext ec)
                {
@@ -5823,11 +5438,23 @@ namespace Mono.MonoBASIC {
                                loop = ig.DefineLabel ();
                                ig.MarkLabel (loop);
 
+                               FieldBase fb = null;
+                               if ( variable.VariableInfo.Alias != null )
+                               {
+                                       fb = variable.VariableInfo.GetFieldAlias(ec);
+
+                                       if( (fb.ModFlags & Modifiers.STATIC) == 0 )
+                                               ig.Emit (OpCodes.Ldarg_0);
+                               }       
+                                       
                                ig.Emit (OpCodes.Ldloc, copy);
                                ig.Emit (OpCodes.Ldloc, counter);
                                ArrayAccess.EmitLoadOpcode (ig, var_type);
 
-                               variable.EmitAssign (ec, conv);
+                               if ( fb == null)
+                                       variable.EmitAssign (ec, conv);
+                               else
+                                       variable.EmitAssign (ec, conv, fb);
 
                                statement.Emit (ec);
 
@@ -5876,7 +5503,7 @@ namespace Mono.MonoBASIC {
                                        ig.Emit (OpCodes.Ldloc, dim_count [dim]);
 
                                //
-                               // FIXME: Maybe we can cache the computation of `get'?
+                               // FIXME: Maybe we can cache the computation of 'get'?
                                //
                                Type [] args = new Type [rank];
                                MethodInfo get;
@@ -5953,7 +5580,7 @@ namespace Mono.MonoBASIC {
                public AddHandler (Expression evt_id, Expression evt_handler, Location l)
                {
                        EvtId = evt_id;
-                       EvtHandler = evt_handler;
+                       EvtHandler = Parser.SetAddressOf (evt_handler);
                        loc = l;
                        resolved = false;
                        //Console.WriteLine ("Adding handler '" + evt_handler + "' for Event '" + evt_id +"'");
@@ -6035,7 +5662,7 @@ namespace Mono.MonoBASIC {
                public RemoveHandler (Expression evt_id, Expression evt_handler, Location l)
                {
                        EvtId = evt_id;
-                       EvtHandler = evt_handler;
+                       EvtHandler = Parser.SetAddressOf (evt_handler);
                        loc = l;
                }
 
@@ -6089,23 +5716,100 @@ namespace Mono.MonoBASIC {
        }
 
        public class RedimClause {
-               public Expression Expr;
-               public ArrayList NewIndexes;
+               private Expression RedimTarget;
+               private ArrayList NewIndexes;
+               private Expression AsType;
                
-               public RedimClause (Expression e, ArrayList args)
+               private LocalTemporary localTmp = null;
+               private Expression origRedimTarget = null;
+               private StatementExpression ReDimExpr;
+
+               public RedimClause (Expression e, ArrayList args, Expression e_as)
                {
-                       Expr = e;
+                       if (e is SimpleName)
+                               ((SimpleName) e).IsInvocation = false;
+                       if (e is MemberAccess)
+                               ((MemberAccess) e).IsInvocation = false;
+               
+                       RedimTarget = e;
+                       NewIndexes = args;
+                       AsType = e_as;
+               }
+
+               public bool Resolve (EmitContext ec, bool Preserve, Location loc)
+               {
+                       RedimTarget = RedimTarget.Resolve (ec);
+
+                       if (AsType != null) {
+                               Report.Error (30811, loc, "'ReDim' statements can no longer be used to declare array variables");
+                               return false;
+                       }
+                       
+                       if (!RedimTarget.Type.IsArray) {
+                               Report.Error (49, loc, "'ReDim' statement requires an array");
+                               return false;
+                       }
+
+                       ArrayList args = new ArrayList();
+                       foreach (Argument a in NewIndexes) {
+                               if (a.Resolve(ec, loc))
+                                       args.Add (a.Expr);
+                       }
+
+                       for (int x = 0; x < args.Count; x++) {
+                               args[x] = new Binary (Binary.Operator.Addition,
+                                                       (Expression) args[x], new IntLiteral (1), Location.Null);       
+                       }
+
                        NewIndexes = args;
+                       if (RedimTarget.Type.GetArrayRank() != NewIndexes.Count) {
+                               Report.Error (30415, loc, "'ReDim' cannot change the number of dimensions of an array.");
+                               return false;
+                       }
+                       
+                       Type BaseType = RedimTarget.Type.GetElementType();
+                       Expression BaseTypeExpr = MonoBASIC.Parser.DecomposeQI(BaseType.FullName.ToString(), Location.Null);
+                       ArrayCreation acExpr = new ArrayCreation (BaseTypeExpr, NewIndexes, "", null, Location.Null);   
+                       if (Preserve)
+                       {
+                               ExpressionStatement PreserveExpr = null;
+                               if (RedimTarget is PropertyGroupExpr) {
+                                       localTmp = new LocalTemporary (ec, RedimTarget.Type);
+                                       PropertyGroupExpr pe = RedimTarget as PropertyGroupExpr;
+                                       origRedimTarget = new PropertyGroupExpr (pe.Properties, pe.Arguments, pe.InstanceExpression, loc);
+                                       if ((origRedimTarget = origRedimTarget.Resolve (ec)) == null)  {
+                                               Report.Error (-1, loc, "'ReDim' vs PropertyGroup");
+                                               return false;
+                                       }
+                                       PreserveExpr = (ExpressionStatement) new Preserve(localTmp, acExpr, loc);
+                               } else
+                                       PreserveExpr = (ExpressionStatement) new Preserve(RedimTarget, acExpr, loc);
+                               ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, PreserveExpr, loc), loc);
+                       }
+                       else
+                               ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, acExpr, loc), loc);
+                       ReDimExpr.Resolve(ec);  
+                       return true;            
                }
+
+               public void DoEmit (EmitContext ec)
+               {
+                       if (ReDimExpr == null)
+                               return;
+                               
+                       if (localTmp != null && origRedimTarget != null) {
+                               origRedimTarget.Emit (ec);
+                               localTmp.Store (ec);
+                       }
+                       ReDimExpr.Emit(ec);
+               }               
+
        }
 
        public class ReDim : Statement {
                ArrayList RedimTargets;
-               Type BaseType;
                bool Preserve;
 
-               private StatementExpression ReDimExpr;
-
                public ReDim (ArrayList targets, bool opt_preserve, Location l)
                {
                        loc = l;
@@ -6115,51 +5819,16 @@ namespace Mono.MonoBASIC {
 
                public override bool Resolve (EmitContext ec)
                {
-                       Expression RedimTarget;
-                       ArrayList NewIndexes;
-
-                       foreach (RedimClause rc in RedimTargets) {
-                               RedimTarget = rc.Expr;
-                               NewIndexes = rc.NewIndexes;
-
-                               RedimTarget = RedimTarget.Resolve (ec);
-                               if (!RedimTarget.Type.IsArray)
-                                       Report.Error (49, "'ReDim' statement requires an array");
-
-                               ArrayList args = new ArrayList();
-                               foreach (Argument a in NewIndexes) {
-                                       if (a.Resolve(ec, loc))
-                                               args.Add (a.Expr);
-                               }
-
-                               for (int x = 0; x < args.Count; x++) {
-                                       args[x] = new Binary (Binary.Operator.Addition,
-                                                               (Expression) args[x], new IntLiteral (1), Location.Null);       
-                               }
-
-                               NewIndexes = args;
-                               if (RedimTarget.Type.GetArrayRank() != args.Count)
-                                       Report.Error (30415, "'ReDim' cannot change the number of dimensions of an array.");
-
-                               BaseType = RedimTarget.Type.GetElementType();
-                               Expression BaseTypeExpr = MonoBASIC.Parser.DecomposeQI(BaseType.FullName.ToString(), Location.Null);
-                               ArrayCreation acExpr = new ArrayCreation (BaseTypeExpr, NewIndexes, "", null, Location.Null);   
-                               // TODO: we are in a foreach we probably can't reuse ReDimExpr, must turn it into an array(list)
-                               if (Preserve)
-                               {
-                                       ExpressionStatement PreserveExpr = (ExpressionStatement) new Preserve(RedimTarget, acExpr, loc);
-                                       ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, PreserveExpr, loc), loc);
-                               }
-                               else
-                                       ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, acExpr, loc), loc);
-                               ReDimExpr.Resolve(ec);
-                       }
-                       return true;
+                       bool result = true;
+                       foreach (RedimClause rc in RedimTargets)
+                               result = rc.Resolve(ec, Preserve, loc) && result;
+                       return result;
                }
                                
                protected override bool DoEmit (EmitContext ec)
                {
-                       ReDimExpr.Emit(ec);
+                       foreach (RedimClause rc in RedimTargets)
+                               rc.DoEmit(ec);
                        return false;
                }